Lua数据结构和内存占用分析(6)

10节点来说明,这是因为在插入第9条数据后,print打印,系统创建了一个”0.2841796875”字符串,导致节点10在统计消耗的时候计算进去了,具体消耗长度为 25 + 实际长度= 25 + 12 = 37字节,与节点10的消耗吻合。同理节点18的消耗为25 + len(“0.5”) = 28

 

问题二:因为节点101834本身也print打印了字符串,怎么它后面的111935就没有消耗内存?

11为例,理论上节点10打印的”0.0361328125”会消耗内存,但这个字符串在节点6已经创建过了,由于所有短字符串都在stringtable进行管理,只有一份拷贝,所以不再消耗内存。

 

问题三:为什第一个节点内存消耗明显偏高?

这是因为for循环里面local cur = collectgarbage("count")调用,触发了Lua_state->stack指向的内存空间的动态扩容,原理有点类似HashTable内存不够的再分配机制。

综上三个问题,可以把代码调整一下再看:

tab = {}

text = "diff mem"

collectgarbage("stop")

before = collectgarbage("count");

for i = 1, 100 do

    if i == 1 then before = collectgarbage("count"); end

    tab[10000 + i] = i

 

    local cur = collectgarbage("count")

    print(text, cur - before)

    before = collectgarbage("count");

end

 

 

Lua数据结构和内存占用分析

可以看到,在1235917等位置触发内存再分配,对应重新分配的内存是2^0=12^1=22^2=481632大小。NewSize-OldSize差值即新增内存,分别为1-0=12-1=14-2=28-4=416-8=832-16=16,而单个节点大小为0.03125K,整体每次新增内存与上面截图完全吻合。

2.2.3 估算table的内存消耗

创建一个最简单的表{}, lua在调用luaH_new初始化时并不会动态分配arrayhashtable指向的内存,只是创建一个最简单的table管理结构,所以消耗的内存为sizeof(Table) = 56

1、估算tablehashtable的内存消耗

每个Node节点消耗sizeof(Node) = 32。所以对于简单数据(整型、浮点、bool)相对比较好估算,sizeof(Table) + sizeof(Node) * NodeNum。 例如上面的代码,100条记录实际分配的Node节点2^7=128,就是56 + 32 * 128 = 4152

collectgarbage("stop");

before = collectgarbage("count");

tab = {}

for i = 1, 128 do

    tab[10000+i] = i

end

after = collectgarbage("count");

print("total mem:", (after - before)*1024)

 

total mem:      4152.0

 

 

2、估算table中有序数组的内存消耗

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/40d90a672028c9263a52f6444ac70320.html