使用Node.js JSON中的字符串大小是否有限制?

时间:2014-06-11 03:04:45

标签: javascript json node.js

我的Node.js应用程序的一部分涉及从用户接收字符串作为输入并将其存储在JSON文件中。 JSON本身显然对此没有限制,但是Node可以处理成JSON的文本量是否有任何上限?

请注意,我使用MongoDB或任何其他技术进行实际插入 - 这是本机字符串化并使用fs保存到.json文件。

4 个答案:

答案 0 :(得分:27)

V8(构建了JavaScript引擎节点),直到非常最近有hard limit on heap size of about 1.9 GB

由于打破了本机插件周围的V8 API更改,节点v0.10停留在旧版本的V8(3.14)上。节点0.12将更新到最新的V8(3.26),它将打破许多本机模块,但为要引发的1.9 GB堆限制打开了大门。

就目前而言,单个节点进程可以保留不超过1.9 GB的JavaScript代码,对象,字符串等组合。这意味着字符串的最大长度低于1.9 GB。

可以通过使用Buffer来解决这个问题,它将数据存储在V8堆之外(但仍然在你的进程堆中)。只要在JavaScript变量中没有超过1.9 GB的数据,64位构建的节点几乎可以填满所有RAM。


所有这一切,你永远不应该接近这个限制。处理这么多数据时,必须以流的形式处理它。一次内存中的内存永远不会超过几兆字节(最多)。好消息是节点特别适合处理流数据。

你应该问自己一些问题:

  • 您实际从用户那里收到了哪些数据?
  • 您为什么要以JSON格式存储它?
  • 将千兆字节填入JSON真的是个好主意吗? (答案是否定的。)
  • 数据存储后会发生什么?你的代码会读它吗?还有别的吗?

您发布的问题实际上对您实际尝试完成的内容非常模糊。有关更具体的建议,请使用更多信息更新您的问题。

如果您希望数据永远不会那么大,只需在输入上抛出合理的10 MB或其他内容,将其全部缓冲,然后使用JSON.stringify

如果您希望处理更大的数据,则需要将输入直接流式传输到磁盘。如果您需要在数据进入磁盘之前处理/修改数据,请查看transform streams。例如,有modules that deal with streaming JSON

答案 1 :(得分:9)

“vanilla”nodeJS(v0.10.28)中的最大字符串大小是1GB的大概。

如果您赶时间,可以使用自加倍字符串测试支持的最大字符串大小。测试的系统有8GB的RAM,大多数未使用。

x = 'x';
while (1){ 
     x = ''+x+x; // string context
     console.log(x.length);
}

2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
FATAL ERROR: JS Allocation failed - process out of memory
Aborted (core dumped)

在另一项测试中,我一次获得1,000,000,000个一个字符用于循环。

现在评论家可能会说,“等等,JSON怎么样。问题是关于JSON的!”我会喊JAVASCRIPT中没有JSON对象,JS类型是Object,Array,String,Number等....而且JSON是一个字符串表示,这个问题归结为最长的允许字符串。但是为了仔细检查,让我们添加一个JSON.stringify调用来解决JSON转换问题。

代码

x = 'x';
while (1){ 
     x = ''+x+x; // string context
     console.log(JSON.stringify({a:x}).length);
}

期望:JSON字符串的大小将从大于2开始,因为第一个对象将为10个字符串化为“{”a“:”xx“}”。在属性a中的x字符串变大之前,它不会开始加倍。它可能会在256M左右失败,因为它可能会在字符串化中生成第二个副本。回想一下,字符串化与原始对象无关。

结果:

10
12
16
24
40
72
136
264
520
1032
2056
4104
8200
16392
32776
65544
131080
262152
524296
1048584
2097160
4194312
8388616
16777224
33554440
67108872
134217736
268435464

非常符合预期......

现在这些限制可能与在nodeJS项目中实现JS的C / C ++代码有关,此时我认为这与Chrome浏览器中使用的V8代码相同。

博客文章中有证据显示人们重新编译nodeJS以绕过旧版本的内存限制。还有许多nodejs命令行开关。我还没有测试过这种效果。

答案 2 :(得分:1)

这是一个很好的问题,但我认为您需要担心的上限不涉及最大JSON字符串大小。

在我看来,您需要担心的限制是您希望在处理用户请求时阻止请求线程多长时间。

超过1MB的任何字符串大小都会让用户上传几秒钟,10兆字节可能需要几分钟。收到请求后,服务器将花费几百毫秒到几秒来解析数据结构,导致用户体验非常差(解析JSON 非常昂贵)

带宽和服务器处理时间将掩盖JSON对字符串大小的任何限制。

答案 3 :(得分:0)

node.js中字符串的最大长度由基础Javascript引擎“ V8”定义。在V8中,最大长度与堆大小无关。字符串的大小实际上受优化对象布局定义的限制的约束。请参阅https://chromium-review.googlesource.com/c/v8/v8/+/2030916,这是对V8中字符串最大长度的最新更改(2020年2月)。提交消息说明了随时间的不同长度。限制已经从大约256MB增加到1GB,然后又回到了512MB(在64位V8平台上)。