编程语言|关于NodeMCU的内存测试

前言 正在用NodeMCU做项目,Lua语言很快就能拿来用,比用C语言开发快很多.但是突出的问题便是内存溢出.以前使用stm32时从没遇到过这个问题,觉得c语言中的联合体是给上世纪的51用的.自从这个项目进行的很顺利的到达预期80%的功能的时候,突然内存溢出触发看门狗时,心态就炸了.先是花了几天优化,憋出了几k内存,但是是基于阉割了一些冗余代码的基础上.再经历了源码改动未果,Lua协程架构不能有效节省内存之后,开始研究NodeMCU的struct模块,可以与C语言的结构体进行交互.进而引发了我研究各种数据储存的内存使用情况的研究.
实验情况 测试一个空函数占用堆空间

heap0=0 heap1=0 heap0=node.heap() function fun() end heap1=node.heap() print('@heap',heap0,heap1,(heap0-heap1))

@heap 40576 40376 200
可以看出一个空函数占用200B堆空间
测试一个空表占用空间
heap0=0 heap1=0 heap0=node.heap() s={} heap1=node.heap() print('@heap',heap0,heap1,(heap0-heap1))

@heap 40576 40496 80
测试在表中创建一个数字的内存开销
heap0=0 heap1=0 s={} heap0=node.heap() s[1]=1 heap1=node.heap() print('@heap',heap0,heap1,(heap0-heap1))

@heap 40496 40432 64
测试单表储存数据开销是否平均
heap0=node.heap() s={1,2,3,4,5,6,7,8,9,10,11,12,13} heap1=node.heap() n=13 print('@heap',heap0,heap1,(heap0-heap1-296-88)/n)

@heap1399363987264 @heap2399363987232 @heap3399363982437.333333333333 @heap4399363982428 @heap5399363982422.4 @heap6399363976029.333333333333 @heap7399363976025.142857142857 @heap8399363976022 @heap9399363976019.555555555556 @heap10399363963230.4 @heap11399363963227.636363636364 @heap12399363963225.333333333333 @heap13399363963223.384615384615 @heap14399363963221.714285714286 @heap15399363963220.266666666667 @heap16399363963219 @heap17399363963217.882352941176 @heap18399363937631.111111111111 @heap19399363937629.473684210526 @heap20399363937628 @heap21399363937626.666666666667 @heap22399363937625.454545454545 @heap23399363937624.347826086957 @heap24399363937623.333333333333 @heap25399363937622.4 @heap26399363937621.538461538462 @heap27399363937620.740740740741 @heap28399363937620 @heap29399363937619.310344827586 @heap30399363937618.666666666667 @heap31399363937618.064516129032 @heap32399363937617.5 @heap33399363937616.969696969697 @heap34399363886431.529411764706 @heap35399363886430.628571428571 @heap36399363886429.777777777778 @heap37399363886428.972972972973 @heap38399363886428.210526315789 @heap39399363886427.487179487179 @heap40399363886426.8 @heap41399363886426.146341463415 @heap42399363886425.52380952381 @heap43399363886424.93023255814 @heap44399363886424.363636363636 @heap45399363886423.822222222222 @heap46399363886423.304347826087 @heap47399363886422.808510638298 @heap48399363886422.333333333333 @heap49399363886421.877551020408 @heap50399363886421.44 @heap51399363886421.019607843137 @heap52399363886420.615384615385 @heap53399363886420.22641509434 @heap54399363886419.851851851852 @heap55399363886419.490909090909 @heap56399363886419.142857142857 @heap57399363886418.80701754386 @heap58399363886418.48275862069 @heap59399363886418.169491525424 @heap60399363886417.866666666667 @heap61399363886417.573770491803 @heap62399363886417.290322580645 @heap63399363886417.015873015873 @heap64399363886416.75 @heap65399363886416.492307692308 @heap66399363784031.757575757576 @heap67399363784031.283582089552 @heap68399363784030.823529411765 @heap69399363784030.376811594203 @heap70399363784029.942857142857 @heap71399363784029.521126760563 @heap72399363784029.111111111111 @heap73399363784028.712328767123 @heap74399363784028.324324324324 @heap75399363784027.946666666667 @heap76399363784027.578947368421 @heap77399363784027.220779220779 @heap78399363784026.871794871795 @heap79399363784026.53164556962 @heap80399363784026.2 @heap81399363784025.876543209877 @heap82399363784025.560975609756 @heap83399363784025.253012048193 @heap84399363784024.952380952381 @heap85399363784024.658823529412 @heap86399363784024.372093023256 @heap87399363784024.091954022989 @heap88399363784023.818181818182 @heap89399363784023.550561797753 @heap90399363784023.288888888889 @heap91399363784023.032967032967 @heap92399363784022.782608695652 @heap93399363784022.537634408602 @heap94399363784022.297872340426 @heap95399363784022.063157894737 @heap96399363784021.833333333333 @heap97399363784021.60824742268 @heap98399363784021.387755102041 @heap99399363784021.171717171717 @heap100 399363784020.96

结论是不可知,时而减少,时而增多,可以设计函数统计下,但是Lua的内存查看比较麻烦,不容易控制.
测试变量储存单数据
heap0=node.heap() s1=1 s2=2 s3=3 s4=4 s5=5 s7=7 s8=8 s9=9 s10=10 s11=11 s12=12 s13=13 heap1=node.heap() print('@heap',heap0,heap1,(heap0-heap1-296)/13)

@heap 40864 39672 68.923076923077
同样的内存变化不确定,时而减少,时而增多.
在函数中单变量储存数字
heap0=0 heap1=0 heap0=node.heap() function fun() s1=1 s2=2 s3=3 s4=4 s5=5 s6=6 s7=7 s8=8 end heap1=node.heap() print('@heap',heap0,heap1,heap0-heap1)

@heap 40576 39752 824
当我把数据增大一些,可用堆竟然增加了
heap0=0 heap1=0 heap0=node.heap() function fun() s1=100000000000000 s2=200000000000000 s3=300000000000000 s4=400000000000000 s5=500000000000000 s6=600000000000000 s7=700000000000000 s8=800000000000000 end heap1=node.heap() print('@heap',heap0,heap1,heap0-heap1)

【编程语言|关于NodeMCU的内存测试】@heap 40576 39800 776
函数中表储存数字
heap0=0 heap1=0 heap0=node.heap() function fun() s={1,2,3,4,5,6,7,8} end heap1=node.heap() print('@heap',heap0,heap1,heap0-heap1)

@heap 40576 40160 416
初步发现占用空间比单变量储存数据更少.
函数中单变量储存字符串
heap0=0 heap1=0 heap0=node.heap() function fun() s1='1' s2='2' s3='3' s4='4' s5='5' s6='6' s7='7' s8='8' end heap1=node.heap() print('@heap',heap0,heap1,heap0-heap1)

@heap 40576 39568 1008

在函数中使用表储存数字,直接打印字面量
heap0=0 heap1=0 heap0=node.heap() function fun() s1={1,2,3,4,5,6,7,8} print(1,2,3,4,5,6,7,8) end heap1=node.heap() print('@heap',heap0,heap1,heap0-heap1)

@heap 40576 40072 504
在函数中使用表储存数字,通过index打印出来
heap0=0 heap1=0 heap0=node.heap() function fun() s1={1,2,3,4,5,6,7,8} print(s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8]) end heap1=node.heap() print('@heap',heap0,heap1,heap0-heap1)

@heap 40576 39984 592
使用pairs函数打印
heap0=0 heap1=0 heap0=node.heap() function fun() s1={1,2,3,4,5,6,7,8} for k,v in ipairs(s1) do print(k,v) end end heap1=node.heap() print('@heap',heap0,heap1,heap0-heap1)

@heap 40576 40048 528

    推荐阅读