当不使用"--max old space size"标志时,可用内存的默认值是多少



节点:12.16.2

尝试弄清楚在具有内存限制512mb的docker容器中运行的节点应用程序在256mb上使用JavaScript heap out of memory失败的原因,以及是否将限制增加到1500mb而不是大约使用700mb失败。看起来只有50%的空间给了老一代对象,但我找不到任何关于这种行为的文档。

将旧空间大小设置为总可用内存的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推荐的";最大旧空间大小";。

当--是否未使用最大旧空间大小标志?

可用内存可以使用V8getHeapStatistics()功能进行检查:

const v8 = require('v8');
// Output available memory in GBs
console.log(v8.getHeapStatistics().heap_size_limit / 1024 ** 3);

最新更新