今天我运行了我的文件系统索引脚本来刷新RAID文件索引,4小时后它崩溃了,出现了以下错误。
[md5:] 241613/241627 97.5%
[md5:] 241614/241627 97.5%
[md5:] 241625/241627 98.1%
Creating missing list... (79570 files missing)
Creating new files list... (241627 new files)
<--- Last few GCs --->
11629672 ms: Mark-sweep 1174.6 (1426.5) -> 1172.4 (1418.3) MB, 659.9 / 0 ms [allocation failure] [GC in old space requested].
11630371 ms: Mark-sweep 1172.4 (1418.3) -> 1172.4 (1411.3) MB, 698.9 / 0 ms [allocation failure] [GC in old space requested].
11631105 ms: Mark-sweep 1172.4 (1411.3) -> 1172.4 (1389.3) MB, 733.5 / 0 ms [last resort gc].
11631778 ms: Mark-sweep 1172.4 (1389.3) -> 1172.4 (1368.3) MB, 673.6 / 0 ms [last resort gc].
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x3d1d329c9e59 <JS Object>
1: SparseJoinWithSeparatorJS(aka SparseJoinWithSeparatorJS) [native array.js:~84] [pc=0x3629ef689ad0] (this=0x3d1d32904189 <undefined>,w=0x2b690ce91071 <JS Array[241627]>,L=241627,M=0x3d1d329b4a11 <JS Function ConvertToString (SharedFunctionInfo 0x3d1d3294ef79)>,N=0x7c953bf4d49 <String[4]\: ,\n >)
2: Join(aka Join) [native array.js:143] [pc=0x3629ef616696] (this=0x3d1d32904189 <undefin...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [/usr/bin/node]
2: 0xe2c5fc [/usr/bin/node]
3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/bin/node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/bin/node]
5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/usr/bin/node]
6: v8::internal::Runtime_SparseJoinWithSeparator(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/bin/node]
7: 0x3629ef50961b
服务器配备了16gb内存和24gb SSD swap。我非常怀疑我的脚本超过了36gb的内存。至少它不应该
脚本创建的文件索引被存储为带有文件元数据(修改日期、权限等,没有大数据)的对象阵列。
这里是完整的脚本代码。 http://pastebin.com/mjaD76c3
我在过去使用这个脚本时已经遇到了奇怪的节点问题,迫使我把索引分成多个文件,因为节点在处理像字符串这样的大文件时出现了故障。有什么办法可以改善nodejs对巨大数据集的内存管理吗?
如果我没记错的话,在V8中有一个严格的标准限制,如果你不手动增加内存,那么内存使用量大约为1.7GB。
在我们的一个产品中,我们在部署脚本中遵循这个解决方案。
node --max-old-space-size=4096 yourFile.js
也会有一个新的空间命令,但正如我在这里看到的。a-tour-of-v8-garbag-collection 新空间只收集新创建的短期数据,旧空间包含所有引用的数据结构,这在你的情况下应该是最佳选择。
我在尝试用VSCode调试时遇到了这个问题,所以只想补充一下,这就是你如何在调试设置中加入参数。
你可以把它添加到launch.json
中的配置的runtimeArgs
属性中。
见下面的例子。
{
"version": "0.2.0",
"configurations": [{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}\\server.js"
},
{
"type": "node",
"request": "launch",
"name": "Launch Training Script",
"program": "${workspaceRoot}\\training-script.js",
"runtimeArgs": [
"--max-old-space-size=4096"
]
}
]}
即使在设置了 --max-old-space-size之后,我仍在为这个问题而挣扎。
然后我意识到需要在karma脚本前加上选项--max-old-space-size。
另外,最好同时指定两种语法 --max-old-space-size 和 --max_old_space_size 我的karma脚本。
node --max-old-space-size=8192 --optimize-for-size --max-executable-size=8192 --max_old_space_size=8192 --optimize_for_size --max_executable_size=8192 node_modules/karma/bin/karma start --single-run --max_new_space_size=8192 --prod --aot