概述
字符串存储分为两种:
- 一种是通过计算所得,这种字符串存储在RAM空间中;
- 而另一种是原始字符串,写在程序内部或者控件原始属性中,这种字符串存储在ROM(flash)中;
比如:
str s;
s="ABCD"+"1234";
echo(s);
其中"ABCD"和"1234"这两个字符串存储在ROM空间内,而变量s对应的字符串“ABCD1234”则存储到RAM空间中,而对于系统来说,ROM空间相对比较宽松,我们重点要关注RAM空间的字符串,因为RAM空间非常珍贵;
str s;
s="ABCD"; //字符串s被赋值,因此变量s也算计算所得,使用RAM空间存储;
有关RAM字符串存储区的大小
字符串(含二进制),系统的变量分为数值和字符串,对于字符串来说,在系统传递时实际传递的是字符串存储区的存储地址;
字符串的存储为了防止存储碎片,采用固定长度对齐的方案,和字符串有关的配置如下:
//以下是SHMICTRL-V1/V2/V3系列芯片对应的配置:
#define DEF_MaxString 1024 //字符串的最大长度,含数组
#define DEF_BlockSize 16 //字符串区的块大小,如果分配多区,统一大小
#define DEF_BlockNum 512 //字符串区的数量,最大4096,同时多个在处理内存分配的前提下,可以设置不同大小
- DEF_MaxString 参数是指设置的str a; 这个字符串变量所支持的最大长度,目前设置的是1024字节,当字符串超过1024字节时,可能会遇见自动截取或取消执行的现象;
- DEF_BlockSize 是指存储区每个数据块的大小,目前设置的是16字节,也就是说"A" 和"ABCD"这两个字符串都占用一个数据块,也就是占用16字节下的字符串占用空间一致;
- DEF_BlockNum 存储区数据块的块数,目前设置512块,也就是字符串存储区总大小为512X16=8192字节
二进制数据
int bs1;
int bs2;
bs1=newbin(16);
bs2=newbin(2);
......
freestr(bs2);
freestr(bs1);
bs1和bs2实际上是两个二进制字符串对应的地址,受DEF_BlockSize配置,每块16字节,因此bs1和bs2使用的RAM控件是一致的,都是一个数据块(16字节);
二进制字符对应的地址存储在bs1中,类型是一个数字,因此无论bs1变量是否被销毁,对应的二进制字符串都不会被销毁,因此需要手动使用freestr语句来清除二进制数据;
垃圾回收
str s;
s="ABCD"+"1234";
s="";
对于上面代码第二行,s变量被赋值计算结果"ABCD1234",这个结果会在内存中申请一个数据块来存储,而到了第三行,变量s又被赋值,顺便说一下,即便是空字符串,也需要一个数据块来存储;变量s被赋值后,原有的对应的"ABCD1234"这个数据块并没有被覆盖,只是给变量s从新换了一个新数据块的地址;
同样,当函数返回,函数内部对应的字符串变量也同时被释放,而这些变量对应的存储数据块却没有被释放;因此这样累积下去,存储空间就会被用满,这样就会要进行清理,我们称之为“垃圾回收”;
“垃圾回收”触发条件是存储空间用完之后自动进行垃圾回收,将没有被变量对应的存储空间释放出来,因此程序员无需过多关注,只是需要了解而已。
小技巧
对于长度比较大的字符串,优先进行手工回收,例子如下:
str s;
s="abcdedfg........."; //长度比较大的字符串,占用多个数据块存储
//.....变量s 参与的运算代码
s=""; //重新赋值,此时变量只占用1个数据块,前面的多个数据块在垃圾回收后会被释放出来