背景
有天我们执行了类似的lua代码,往一个table中存入大量数据,在进行多次collectgarbage(“collect”)回收
ab = {};
for i = 1, 1000000 do ab[#ab + 1] = {string.format("aaaaa_%d_%d", i, math.random(1, 1000000)), string.format("aaaaa_%d_%d", i, math.random(1, 1000000)), string.format("aaaaa_%d_%d", i, math.random(1, 1000000)), string.format("aaaaa_%d_%d", i, math.random(1, 1000000)), string.format("aaaaa_%d_%d", i, math.random(1, 1000000)), string.format("aaaaa_%d_%d", i, math.random(1, 1000000)),[string.format("aaaaa_%d_%d", i, math.random(1, 1000000))]= {string.format("aaaaa_%d_%d", i, math.random(1, 1000000)), string.format("aaaaa_%d_%d", i, math.random(1, 1000000)), string.format("aaaaa_%d_%d", i, math.random(1, 1000000)),string.format("aaaaa_%d_%d", i, math.random(1, 1000000))} } end
print(collectgarbage("count"))
661211.734375
ab = nil
collectgarbage("collect");
collectgarbage("collect");
collectgarbage("collect");
collectgarbage("collect");
print(collectgarbage("count"))
591.5625
可以看到多次collect后count数量已经降下,而使用linux上top指令看到RES并未减少,于是想要使用valgrind观察看luajit内存的申请释放情况
启动带有vgdb模式的valgrind
窗口1
valgrind --vgdb=yes --vgdb-error=0 --tool=massif --detailed-freq=1 --stacks=yes $LD_LIBRARY_PATH/main -server_id 1
新的控制台使用gdb连接valgrind
窗口2
gdb /home/cc/main
target remote | vgdb
在我们需要使用valgrind截取内存情况的代码处打上断点
窗口2
b lua_engine.cpp:278
开始进程
窗口2
continue
当我们执行代码后,断点生效,使用指令截取当前镜像
monitor detailed_snapshot snapshot001
使用ms_print 解析相关内容
ms_print snapshot001 > snapshot001.txt
进程退出头查看全部结果
MB
317.4^ ##
| # @@@@@@@@@@@
| # @@@@ @ @@@ @@
| @# @@@@ @ @@@ @
| @@@@# @@@@ @ @@@ @ @
| @@@@@@@@ @# @@@@ @ @@@ @ @@@
| @@@@@@@@@ @ @@ @# @@@@ @ @@@ @ @@@@
| @@@@@ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@
| @@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@@
| @@@@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@
| @@@@@ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@
| @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@
| @@@@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @
| @@@@@@ @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @@@@@
| @@@ @@ @ @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @@@@@@@@@@
| @@@ @@ @ @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @@@@@@@@@@
| @@@ @@ @ @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @@@@@@@@@@
| @@@ @@ @ @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @@@@@@@@@@
| @@@ @@ @ @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @@@@@@@@@@
| @@@ @@ @ @@@@ @ @ @@@@ @ @@@ @@@ @ @@ @# @@@@ @ @@@ @ @@@@@@ @@@@@@@@@@
0 +----------------------------------------------------------------------->Gi
0 2.893
snapshot镜像1
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
0 0 0 0 0 0
00.00% (0B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
1 44,224,718 105,769,744 105,299,512 449,064 21,168
99.56% (105,299,512B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->97.43% (103,056,745B) 0x10701A49: CMemoryPool::AddNewBlob() (mempool.cpp:190)
->01.40% (1,477,976B) 0x6670D0C: lj_mem_realloc (lj_gc.c:877)
snapshot镜像37
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
37 2,290,638,220 300,213,592 270,958,055 29,234,633 20,904
90.26% (270,958,055B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->40.91% (122,825,136B) 0x6670D0C: lj_mem_realloc (lj_gc.c:877)
snapshot镜像52
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
52 3,030,866,900 105,535,880 105,451,090 64,046 20,744
99.92% (105,451,090B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->97.65% (103,056,745B) 0x10701A49: CMemoryPool::AddNewBlob() (mempool.cpp:190)
->02.01% (2,120,128B) 0x6670D0C: lj_mem_realloc (lj_gc.c:877)
结论
- 可以看出 在执行for循环的前后,lj_mem_realloc占用的内存从低(01.40%)到高(40.91%),最高超过总内存的40.91%,经过collectgarbage(“collect”);之后,lj_mem_realloc锁占用的内存又回到初始水平02.01%
- top看到不会res占用不会下降的问题,应该是由于
- https://stackoverflow.com/questions/47508165/will-processs-res-memory-drop-after-memory-freed#comment81972425_47508165
- https://stackoverflow.com/questions/13232119/memory-usage-doesnt-decrease-when-free-used
- https://stackoverflow.com/questions/55294985/does-malloc-reserve-more-space-while-allocating-memory
- 当其他进程占用内存后, 该进程的内存在top中的res便会下降