簡體   English   中英

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

[英]Is there a limit on the size of a string in JSON with Node.js?

我的 Node.js 應用程序的一部分涉及從用戶接收字符串作為輸入並將其存儲在 JSON 文件中。 JSON 本身顯然對此沒有限制,但是 Node 可以處理成 JSON 的文本數量有上限嗎?

請注意,我沒有使用 MongoDB 或任何其他技術進行實際插入 - 這是本機字符串化並使用fs保存到 .json 文件。

V8(JavaScript引擎節點在建),直到最近有一個關於1.9 GB的堆大小硬限制

由於破壞了圍繞原生插件的 V8 API 更改,Node v0.10 停留在舊版本的 V8 (3.14) 上。 Node 0.12 將更新到最新的 V8 (3.26),這將破壞許多本機模塊,但為提高 1.9 GB 堆限制打開了大門。

因此,作為它的立場,單個節點的過程能保持不超過1.9 GB的JavaScript代碼,對象,字符串等相結合 這意味着字符串的最大長度小於 1.9 GB。

可以通過使用Buffer來解決這個問題,它在 V8 堆之外(但仍在您的進程的堆中)存儲數據。 只要 JavaScript 變量中的數據不超過 1.9 GB,一個 64 位構建的節點幾乎可以填滿您的所有 RAM。


盡管如此,你永遠不應該接近這個極限。 處理這么多數據時,必須把它當成一個流來處理。 一次您的內存永遠不應該超過幾兆字節(最多)。 好消息是 node 特別適合處理流數據。

你應該問自己一些問題:

  • 你實際上從用戶那里收到什么樣的數據?
  • 為什么要以JSON格式存儲?
  • 將千兆字節填充到 JSON 中真的是個好主意嗎? (答案是不。)
  • 數據存儲之后會發生什么? 你的代碼會讀取它嗎? 還有什么?

您發布的問題實際上關於您實際嘗試完成的內容非常含糊。 如需更具體的建議,請使用更多信息更新您的問題。

如果您希望數據永遠不會那么大,只需在輸入上設置 10 MB 或其他內容的合理限制,將其全部緩沖,然后使用JSON.stringify

如果您希望處理更大的數據,則需要將輸入直接流式傳輸到磁盤。 如果您需要在數據進入磁盤之前處理/修改數據,請查看轉換流 例如,有處理流式 JSON 的模塊

“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 類型是對象、數組、字符串、數字等......並且由於 JSON 是字符串表示,這個問題歸結為最長允許的字符串是什么。 但為了仔細檢查,讓我們添加一個 JSON.stringify 調用來解決 JSON 轉換。

代碼

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

期望: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

和預期的差不多......

現在這些限制很可能與 nodeJS 項目中實現 JS 的 C/C++ 代碼有關,我認為這與 Chrome 瀏覽器中使用的 V8 代碼相同。

博客文章中有證據表明人們重新編譯 nodeJS 以解決舊版本中的內存限制。 還有一些 nodejs 命令行開關。 我還沒有測試過任何這樣的效果。

node.js 中字符串的最大長度由底層 Javascript 引擎“V8”定義。 在 V8 中,最大長度與堆大小無關。 字符串的大小實際上受優化對象布局定義的限制。 請參閱https://chromium-review.googlesource.com/c/v8/v8/+/2030916 ,這是最近(2020 年 2 月)對 V8 中字符串最大長度的更改。 提交消息解釋了隨時間的不同長度。 限制從大約 256MB 變為 1GB,然后又回到 512MB(在 64 位 V8 平台上)。

這是一個很好的問題,但我認為您需要擔心的上限不涉及最大 JSON 字符串大小。

在我看來,您需要擔心的限制是您希望在處理用戶請求時阻塞請求線程多長時間。

任何超過 1MB 的字符串大小都需要用戶幾秒鍾才能上傳,而 10 兆字節可能需要幾分鍾。 收到請求后,服務器將需要幾百毫秒到幾秒解析到數據結構導致非常糟糕的用戶體驗(解析JSON是非常昂貴)

帶寬和服務器處理時間將掩蓋 JSON 可能對字符串大小的任何限制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM