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

Hyd*_*mal 23 javascript json node.js

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

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

jos*_*736 28

V8(JavaScript引擎节点在建),直到非常最近有一个关于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.

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


所有这一切,你永远不应该接近这个限制.在处理这么多数据时,您必须将其作为流处理.一次内存永远不会超过几兆(最多).好消息是节点特别适合处理流数据.

你应该问自己一些问题:

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

你发布的问题实际上是非常模糊的,你实际上要完成什么.有关更具体的建议,请使用更多信息更新您的问题.

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

如果您希望处理更大的数据,则需要将输入直接流式传输到磁盘.如果需要在数据进入磁盘之前处理/修改数据,请查看转换流.例如,有些模块可以处理流式JSON.


Pau*_*aul 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)
Run Code Online (Sandbox Code Playgroud)

在另一个测试中,我一次获得1,000,000,000个一个char用于循环.

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

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

期望:JSON字符串的大小将从大于2开始,因为第一个对象将字符串化为"{"a":"xx"}'为10个字符.在属性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
Run Code Online (Sandbox Code Playgroud)

几乎像预期的那样......

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

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