今天,我运行了文件系统索引的脚本来刷新RAID文件索引,4h后它崩溃了,出现以下错误:
[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 RAM和24gb SSD交换盘。我非常怀疑我的脚本内存超过了36gb。至少不应该是这样
脚本创建文件索引存储为对象数组与文件元数据(修改日期,权限等,没有大数据)
以下是完整的脚本代码:
http://pastebin.com/mjaD76c3
我已经经历了奇怪的节点问题在过去与这个脚本迫使我eg。分割索引到多个文件作为节点是故障时,工作在这样的大文件字符串。对于庞大的数据集,有什么方法可以改善nodejs的内存管理吗?
我遇到这个问题时,试图调试与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"
]
}
]}
我最近遇到了同样的问题,遇到了这个线程,但我的问题是React应用程序。下面对节点启动命令的更改解决了我的问题。
语法
node --max-old-space-size=<size> path-to/fileName.js
例子
node --max-old-space-size=16000 scripts/build.js
为什么max-old-space-size是16000 ?
基本上,它取决于分配给该线程的内存和您的节点设置。
如何验证和给出正确的尺寸?
这基本上是v8引擎。下面的代码帮助你理解你的本地节点v8引擎的堆大小。
const v8 = require('v8');
const totalHeapSize = v8.getHeapStatistics().total_available_size;
const totalHeapSizeGb = (totalHeapSize / 1024 / 1024 / 1024).toFixed(2);
console.log('totalHeapSizeGb: ', totalHeapSizeGb);
我只是想补充一点,在一些系统中,即使使用——max-old-space-size来增加节点内存限制,这也是不够的,而且会出现这样的操作系统错误:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)
在这种情况下,可能是因为您达到了每个进程的最大mmap。
可以通过运行命令查看max_map_count
sysctl vm.max_map_count
并通过跑步来增加它
sysctl -w vm.max_map_count=655300
并通过添加这一行来修复它,使其在重新启动后不被重置
vm.max_map_count=655300
在/etc/sysctl.conf文件中。
点击这里查看更多信息。
分析误差的一个很好的方法是用strace运行该过程
strace node --max-old-space-size=128000 my_memory_consuming_process.js
最近,在我的一个项目中遇到了同样的问题。尝试了一些事情,任何人都可以尝试调试以确定根本原因:
正如每个人建议的那样,通过添加以下命令来增加节点的内存限制:
{
"脚本":{
"server":"node——max-old-space-size={size-value} server/index.js"
}
}
这里size-value我已经为我的应用程序定义了1536(因为我的kubernetes pod内存是2 GB的限制,请求1.5 GB)
因此,始终根据前端基础设施/架构限制(略小于限制)定义size-value。
在上面的命令中,使用——max-old-space-size命令在node之后,而不是文件名server/index.js之后。
If you have ngnix config file then check following things:
worker_connections: 16384 (for heavy frontend applications)
[nginx default is 512 connections per worker, which is too low for modern applications]
use: epoll (efficient method) [nginx supports a variety of connection processing methods]
http: add following things to free your worker from getting busy in handling some unwanted task. (client_body_timeout , reset_timeout_connection , client_header_timeout,keepalive_timeout ,send_timeout).
Remove all logging/tracking tools like APM , Kafka , UTM tracking, Prerender (SEO) etc middlewares or turn off.
Now code level debugging: In your main server file , remove unwanted console.log which is just printing a message.
Now check for every server route i.e app.get() , app.post() ... below scenarios:
Data => if(Data) res.send(Data) //你真的需要等待数据或API返回一些我必须等待的响应吗??,如果不是这样修改:
data => res.send(data) // this will not block your thread, apply everywhere where it's needed
else part: if there is no error coming then simply return res.send({}) , NO console.log here.
error part: some people define as error or err which creates confusion and mistakes. like this:
`error => { next(err) } // here err is undefined`
`err => {next(error) } // here error is undefined`
`app.get(API , (re,res) =>{
error => next(error) // here next is not defined
})`
remove winston , elastic-epm-node other unused libraries using npx depcheck command.
In the axios service file , check the methods and logging properly or not like :
if(successCB) console.log("success") successCB(response.data) // here it's wrong statement, because on success you are just logging and then `successCB` sending outside the if block which return in failure case also.
Save yourself from using stringify , parse etc on accessive large dataset. (which i can see in your above shown logs too.
最后但并非最不重要的是,每当应用程序崩溃或pod重新启动时,都要检查日志。在日志中特别查找这部分:安全上下文
这将告诉你为什么,在哪里,谁是背后的崩溃的罪魁祸首。
我今天也遇到了同样的问题。对我来说,问题是,我试图在我的NextJS项目的数据库中导入大量数据。
所以我所做的是,我像这样安装win-node-env包:
yarn add win-node-env
因为我的开发机器是Windows。我在本地安装,而不是在全球安装。你也可以像这样全局安装它:yarn global add win-node-env
然后在包装中。我的NextJS项目的json文件,我添加了另一个启动脚本,像这样:
"dev_more_mem": "NODE_OPTIONS=\"--max_old_space_size=8192\" next dev"
在这里,我传递节点选项,即。设置8GB为上限。
我的包裹。Json文件看起来像这样:
{
"name": "my_project_name_here",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"dev_more_mem": "NODE_OPTIONS=\"--max_old_space_size=8192\" next dev",
"build": "next build",
"lint": "next lint"
},
......
}
然后我这样运行它:
yarn dev_more_mem
对我来说,我只在我的开发机器上遇到了这个问题(因为我正在导入大数据)。因此有了这个解决方案。我想分享一下,因为它可能对其他人有用。