背景

有天我们执行了类似的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)

结论

  1. 可以看出 在执行for循环的前后,lj_mem_realloc占用的内存从低(01.40%)到高(40.91%),最高超过总内存的40.91%,经过collectgarbage(“collect”);之后,lj_mem_realloc锁占用的内存又回到初始水平02.01%
  2. 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便会下降

发表评论