node.js - 不使用 `--max-old-space-size` 标志时,可用内存的默认值是多少?
问题描述
节点:12.16.2
尝试找出为什么在具有内存限制的 docker 容器中运行的节点应用程序在on时512mb
失败,以及如果将限制增加到大约时失败。看起来只有 50% 的空间分配给老一代对象,但我找不到任何关于这种行为的文档。JavaScript heap out of memory
256mb
1500mb
700mb
将旧空间大小设置为总可用内存的 70% 左右是否正确(剩余空间是否足以用于其他 v8 内存部分)?
错误日志
<--- Last few GCs --->
[1:0x565508ac6740] 26332 ms: Mark-sweep 255.3 (257.9) -> 254.3 (257.3) MB, 85.7 / 0.0 ms (+ 65.2 ms in 24 steps since start of marking, biggest step 6.6 ms, walltime since start of marking 162 ms) (average mu = 0.239, current mu = 0.259) allocation fa[1:0x565508ac6740] 26447 ms: Mark-sweep 255.6 (258.1) -> 253.6 (256.3) MB, 112.6 / 0.0 ms (average mu = 0.159, current mu = 0.021) allocation failure scavenge might not succeed
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0x565505bea959]
1: StubFrame [pc: 0x565505beb82d]
Security context: 0x229e3f6008d1 <JSObject>
2: /* anonymous */(aka /* anonymous */) [0x278bb3a93ad9] [/app/server.js:~1] [pc=0x180e9c58e6b7](this=0x3479357404b1 <undefined>,0x02f1a1a468a9 <String[30]: defer="defer" charset="utf-8">,0x347935743389 <String[#9]: anonymous>,0x14f217f67ed9 <String[#11]: crossorigin>)
3: /* anonymous */(aka /* anonymous */) [0x...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
节点报告
{
"header": {
"reportVersion": 2,
"event": "Allocation failed - JavaScript heap out of memory",
"trigger": "FatalError",
"filename": "report.20200929.110012.1.0.001.json",
"dumpEventTime": "2020-09-29T11:00:12Z",
"dumpEventTimeStamp": "1601377212975",
"processId": 1,
"threadId": null,
"cwd": "/app",
"commandLine": [
"node",
"--max-http-header-size=80000",
"--inspect=0.0.0.0",
"/app/server.js"
],
"nodejsVersion": "v12.16.2",
"wordSize": 64,
"arch": "x64",
"platform": "linux",
"componentVersions": {
"node": "12.16.2",
"v8": "7.8.279.23-node.34",
"uv": "1.34.2",
"zlib": "1.2.11",
"brotli": "1.0.7",
"ares": "1.15.0",
"modules": "72",
"nghttp2": "1.40.0",
"napi": "5",
"llhttp": "2.0.4",
"http_parser": "2.9.3",
"openssl": "1.1.1e",
"cldr": "36.0",
"icu": "65.1",
"tz": "2019c",
"unicode": "12.1"
},
"release": {
"name": "node",
"lts": "Erbium",
"headersUrl": "https://unofficial-builds.nodejs.org/download/release/v12.16.2/node-v12.16.2-headers.tar.gz",
"sourceUrl": "https://unofficial-builds.nodejs.org/download/release/v12.16.2/node-v12.16.2.tar.gz"
},
"osName": "Linux",
"osRelease": "4.19.76-linuxkit",
"osVersion": "#1 SMP Tue May 26 11:42:35 UTC 2020",
"osMachine": "x86_64",
"cpus": [
{
"model": "Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz",
"speed": 2208,
"user": 7626100,
"nice": 0,
"sys": 3549100,
"idle": 3029580300,
"irq": 0
},
{
"model": "Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz",
"speed": 2208,
"user": 7502400,
"nice": 0,
"sys": 3600100,
"idle": 3030348500,
"irq": 0
}
],
"networkInterfaces": [
{
"name": "lo",
"internal": true,
"mac": "00:00:00:00:00:00",
"address": "127.0.0.1",
"netmask": "255.0.0.0",
"family": "IPv4"
},
{
"name": "eth0",
"internal": false,
"mac": "02:42:ac:11:00:02",
"address": "172.17.0.2",
"netmask": "255.255.0.0",
"family": "IPv4"
}
],
"host": "1fcf963ff82d"
},
"javascriptStack": {
"message": "No stack.",
"stack": [
"Unavailable."
]
},
"nativeStack": [
],
"javascriptHeap": {
"totalMemory": 269869056,
"totalCommittedMemory": 268494816,
"usedMemory": 265315384,
"availableMemory": 3780432,
"memoryLimit": 271581184,
"heapSpaces": {
"read_only_space": {
"memorySize": 262144,
"committedMemory": 33088,
"capacity": 32808,
"used": 32808,
"available": 0
},
"new_space": {
"memorySize": 2097152,
"committedMemory": 1043808,
"capacity": 1047456,
"used": 26608,
"available": 1020848
},
"old_space": {
"memorySize": 150872064,
"committedMemory": 150868648,
"capacity": 149710672,
"used": 149710672,
"available": 0
},
"code_space": {
"memorySize": 2002944,
"committedMemory": 1914816,
"capacity": 1783680,
"used": 1783680,
"available": 0
},
"map_space": {
"memorySize": 2625536,
"committedMemory": 2625240,
"capacity": 2217840,
"used": 2217840,
"available": 0
},
"large_object_space": {
"memorySize": 111386624,
"committedMemory": 111386624,
"capacity": 110999232,
"used": 110999232,
"available": 0
},
"code_large_object_space": {
"memorySize": 622592,
"committedMemory": 622592,
"capacity": 544544,
"used": 544544,
"available": 0
},
"new_large_object_space": {
"memorySize": 0,
"committedMemory": 0,
"capacity": 1047456,
"used": 0,
"available": 1047456
}
}
},
"resourceUsage": {
"userCpuSeconds": 14.3448,
"kernelCpuSeconds": 0.727153,
"cpuConsumptionPercent": 57.9692,
"maxRss": 369463296,
"pageFaults": {
"IORequired": 35,
"IONotRequired": 154703
},
"fsActivity": {
"reads": 10272,
"writes": 2976
}
},
"uvthreadResourceUsage": {
"userCpuSeconds": 9.15498,
"kernelCpuSeconds": 0.423264,
"cpuConsumptionPercent": 36.8394,
"fsActivity": {
"reads": 9192,
"writes": 2976
}
},
"libuv": [
],
"workers": [
],
"environmentVariables": {
"STATIC_PREFIX": "http://localhost:4000/static/",
"NODE_VERSION": "12.16.2",
"HOSTNAME": "1fcf963ff82d",
"YARN_VERSION": "1.22.4",
"SHLVL": "1",
"HOME": "/root",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"DEV_STATIC": "true",
"PWD": "/app",
"NODE_ENV": "production"
},
"userLimits": {
"core_file_size_blocks": {
"soft": 0,
"hard": "unlimited"
},
"data_seg_size_kbytes": {
"soft": "unlimited",
"hard": "unlimited"
},
"file_size_blocks": {
"soft": "unlimited",
"hard": "unlimited"
},
"max_locked_memory_bytes": {
"soft": 83968000,
"hard": 83968000
},
"max_memory_size_kbytes": {
"soft": "unlimited",
"hard": "unlimited"
},
"open_files": {
"soft": 1048576,
"hard": 1048576
},
"stack_size_bytes": {
"soft": 8388608,
"hard": "unlimited"
},
"cpu_time_seconds": {
"soft": "unlimited",
"hard": "unlimited"
},
"max_user_processes": {
"soft": "unlimited",
"hard": "unlimited"
},
"virtual_memory_kbytes": {
"soft": "unlimited",
"hard": "unlimited"
}
},
"sharedObjects": [
"/usr/local/bin/node",
"/usr/lib/libstdc++.so.6",
"/usr/lib/libgcc_s.so.1",
"/lib/ld-musl-x86_64.so.1"
]
}
解决方案
--max-old-space-size
不使用标志时可用内存的默认值是多少?
V8 对默认内存限制的计算相当复杂(并且会不时更改以适应各种情况和用例),您可以查看heap.cc中 Heap::ConfigureHeap 中的源代码。您的猜测是正确的,考虑的因素之一是 V8 内存不应超过总可用内存的一半。这主要针对浏览器用例;在服务器上,没有什么能阻止您使用命令行标志来调整行为以满足您的特定需求。此外,如果 Node 愿意,它可以覆盖 V8 的默认行为。
将旧空间大小设置为总可用内存的 70% 左右是否正确(剩余空间是否足以用于其他 v8 内存部分)?
是的。另请参阅Node.js 推荐的 "max-old-space-size"。
推荐阅读
- java - 无法从搜索框中的动态类型中选择值
- reactjs - Webpack 4 的变化
- excel - 如何创建日期和时间图表
- xml - 使用 Mule 4 将 CSV 转换为 XML
- scikit-learn - 决策树 Sklearn - 如何在每个终端节点构建一个具有一个数据点的成熟树?
- python - 有没有更好的方法可以在不调用两次的情况下恢复 IF 内的 func 参数?
- r - 基于两列分组并创建一个新列以根据每组计算时间差
- javascript - 如何防止默认单击按钮
- python - 错误:urllib2.URLError:
- sql - 包含 SQL + Active Record 的 Rails 迁移产生语法错误