Esp32字符串长度限制
Esp32 string length limit
我发现在 esp32 上运行的应用程序中的行的长度是有限的。
下面是一个生成字符串的应用程序:
main :
loop ::= 2459
text := ""
stamp := "1234567890"
loop.repeat :
text += stamp
print ("$text.size")
如果loop ::= 2458一切正常:
micrcx@micrcx-desktop:~/toit_apps/Hsm3/tests$ toit run test_str.toit
2021-06-02T17:03:43.237309Z: <process initiated>
24580
2021-06-02T17:03:44.575860Z: <process terminated - exit code: 0>
如果loop ::= 2459,出现内存分配错误:
micrcx@micrcx-desktop:~/toit_apps/Hsm3/tests$ toit run test_str.toit
2021-06-02T17:04:03.507773Z: <process initiated>
2021-06-02T17:04:04.907154Z: <stack trace>
EXCEPTION error.
ALLOCATION_FAILED
0: string.+ <sdk>/core/string.toit:274:5
1: main.<block> /home/micrcx/toit_apps/Hsm3/tests/test_str.toit:6:10
2: SmallInteger_.repeat <sdk>/core/numbers.toit:209:3
3: main /home/micrcx/toit_apps/Hsm3/tests/test_str.toit:5:8
4: __entry__.<lambda> <sdk>/core/entry.toit:46:20
2021-06-02T17:04:04.954257Z: <process terminated - exit code: 1>
所有这些错误当然都不是致命的,知道真实的数字就好了,例如,字符串的最大长度、列表、哈希映射等,以便编写一个应用程序不会下降,因为json文件的大小已经超过了允许的数量。
字符串、列表、映射等没有任何实际大小限制
系统只是尝试为这些对象分配space,并在剩余内存不足时报告错误。显然,这对所有对象施加了基本限制:ESP32 最多有 520K RAM,因此任何数据结构都不能超过该大小。
但是,还有更多的限制在起作用。例如,IRAM 内存具有与 DRAM 不同的属性,并且不太适合普通数据。同样,还有一些内存被系统占用了。
对于某些数据结构,如字符串,内存位于连续区域也很重要。碎片会导致无法再分配更大的字符串的情况,因为所有可用内存都位于字符串不适合的较小空洞中。
请注意,使用 +
构建字符串还意味着始终存在前一个字符串的副本,这使程序所需的 space 翻倍。
这是一个示例,表明字符串从根本上不限于 ~25K:
main :
loop ::= 4500
stamp := "1234567890"
text := stamp * loop
print "$text.size"
字符串上的 *
运算符预先分配所需的大小,因此不需要任何其他副本(如在循环中)。
使用 Arduino ESP32 webserver library 我意识到,当我尝试打印构成网页的 HTML 字符串时,我收到以下错误,即使 520K RAM 是相当多的 RAM,而且我有 173K 的空闲堆:
String WEBPAGE = "lots of chars"
Serial.println(WEBPAGE);
Serial.printf("Free heap: %u\n", ESP.getFreeHeap());
我有控制台
E (49837) uart: uart_write_bytes(1159): buffer null
Free heap: 173831
我发现原因是字符串 WEBPAGE 太大(大约 50k 个字符),使用较小的字符串则不会发生错误。
所以下面的函数也不起作用,而是发送和空字符串,我在浏览器上看到一个白色的空白页面。
server.send(200, "text/html", WEBPAGE);
我认为在 ESP32 上使用字符串是一个很大的限制
更多详情here。
我发现在 esp32 上运行的应用程序中的行的长度是有限的。 下面是一个生成字符串的应用程序:
main :
loop ::= 2459
text := ""
stamp := "1234567890"
loop.repeat :
text += stamp
print ("$text.size")
如果loop ::= 2458一切正常:
micrcx@micrcx-desktop:~/toit_apps/Hsm3/tests$ toit run test_str.toit
2021-06-02T17:03:43.237309Z: <process initiated>
24580
2021-06-02T17:03:44.575860Z: <process terminated - exit code: 0>
如果loop ::= 2459,出现内存分配错误:
micrcx@micrcx-desktop:~/toit_apps/Hsm3/tests$ toit run test_str.toit
2021-06-02T17:04:03.507773Z: <process initiated>
2021-06-02T17:04:04.907154Z: <stack trace>
EXCEPTION error.
ALLOCATION_FAILED
0: string.+ <sdk>/core/string.toit:274:5
1: main.<block> /home/micrcx/toit_apps/Hsm3/tests/test_str.toit:6:10
2: SmallInteger_.repeat <sdk>/core/numbers.toit:209:3
3: main /home/micrcx/toit_apps/Hsm3/tests/test_str.toit:5:8
4: __entry__.<lambda> <sdk>/core/entry.toit:46:20
2021-06-02T17:04:04.954257Z: <process terminated - exit code: 1>
所有这些错误当然都不是致命的,知道真实的数字就好了,例如,字符串的最大长度、列表、哈希映射等,以便编写一个应用程序不会下降,因为json文件的大小已经超过了允许的数量。
字符串、列表、映射等没有任何实际大小限制
系统只是尝试为这些对象分配space,并在剩余内存不足时报告错误。显然,这对所有对象施加了基本限制:ESP32 最多有 520K RAM,因此任何数据结构都不能超过该大小。
但是,还有更多的限制在起作用。例如,IRAM 内存具有与 DRAM 不同的属性,并且不太适合普通数据。同样,还有一些内存被系统占用了。
对于某些数据结构,如字符串,内存位于连续区域也很重要。碎片会导致无法再分配更大的字符串的情况,因为所有可用内存都位于字符串不适合的较小空洞中。
请注意,使用 +
构建字符串还意味着始终存在前一个字符串的副本,这使程序所需的 space 翻倍。
这是一个示例,表明字符串从根本上不限于 ~25K:
main :
loop ::= 4500
stamp := "1234567890"
text := stamp * loop
print "$text.size"
字符串上的 *
运算符预先分配所需的大小,因此不需要任何其他副本(如在循环中)。
使用 Arduino ESP32 webserver library 我意识到,当我尝试打印构成网页的 HTML 字符串时,我收到以下错误,即使 520K RAM 是相当多的 RAM,而且我有 173K 的空闲堆:
String WEBPAGE = "lots of chars"
Serial.println(WEBPAGE);
Serial.printf("Free heap: %u\n", ESP.getFreeHeap());
我有控制台
E (49837) uart: uart_write_bytes(1159): buffer null
Free heap: 173831
我发现原因是字符串 WEBPAGE 太大(大约 50k 个字符),使用较小的字符串则不会发生错误。 所以下面的函数也不起作用,而是发送和空字符串,我在浏览器上看到一个白色的空白页面。
server.send(200, "text/html", WEBPAGE);
我认为在 ESP32 上使用字符串是一个很大的限制
更多详情here。