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

对于简单表tab = {}, 一般都是使用tab[#tab + 1] = xxxx 或者 table.insert(tab, xxx) 来插入数据,对于这种典型的场景,table使用的是array的方式存储数据。计算方式,sizeof(Table) + sizeof(TValue) * ArrayNum,其中sizeof(TValue) = 16。同样下面的代码,略作调整,100条记录实际的分配的Array节点也是128, 就是56 + 16 * 128 = 2104.

collectgarbage("stop");

before = collectgarbage("count");

tab = {}

for i = 1, 128 do

    tab[#tab + 1] = i

end

after = collectgarbage("count");

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

 

total mem:      2104.0

 

 

3、估算table嵌套类型的消耗

上面都是用的简单数据类型进行估算,现在考虑下当valueGCObject对象的情况(字符串、表、闭包)。针对一个Node节点,数据组成:

struct Node {

TValue i_val;

  TKey i_key;

} Node;

因此,对于简单的数据类型,TValue里面的结构字段足以存储,但对于复杂类型,TValue里面只是存了一个对象指针GCObject*,而对象本身的内存大小还得单独核算。先看一个简单:

collectgarbage("stop");

before = collectgarbage("count");

tab = {}

tab[10000] = {i}

after = collectgarbage("count");

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

total mem:      160.0

 

A、tab表 sizeof(Table) + sizeof(Node) * 1 = 88

B、{i}使用array来存储,实际消耗 sizeof(Table) + sizeof(TValue) * 1 = 72

C、所以整体消耗: 88 + 72 = 160

4、估算复杂table的数据内存消耗以及与C语言的对比

以一个简单的排行榜列表来进行多维度计算,预计10000条数据,以玩家uid作为key,每条记录存积分和名次。分多个场景进行评估。

场景一:

collectgarbage("stop");

before = collectgarbage("count");

tab = {}

for i = 1, 10000 do

    tab[100000+i] = {score = 100000+i, rank = i}

end

after = collectgarbage("count");

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

total mem:      1724344.0

 

 

A,首先涉及两个字符串”score” “rank” 的消耗。分别是25 + 5 = 30, 25 + 4 = 29 

B,每个小表{score = 100000+i, rank = i}, sizeof(Table) + sizeof(Node) * 2 = 120

C,大表有1W条记录,2^14 = 16384 > 10000sizeof(Table) + sizeof(Node) * 16384 = 524344

D,最终内存占用:30 + 29 + 120 * 10000 + 524344 = 1724403

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

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