forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
worker: add flag to control old space size
This adds a new flag `--thread-max-old-space-size` (name completely provisional). This has two advantages over the existing `--max-old-space-size` flag: 1. It allows setting the old space size for the main thread and using `resourceLimits` for worker threads. Currently `resourceLimits` will be ignored when `--max-old-space-size` is set (see the attached issues). 2. It is implemented using V8's public API, rather than relying on V8's internal flags whose stability and functionality are not guaranteed. The downside is that there are now two flags which (in most cases) do the same thing, so it may cause some confusion. I also think that we should deprecate `--max-old-space-size`, since the semantics feel pretty error-prone, but that's a story for another day. Refs: nodejs#41066 Refs: nodejs#43991 Refs: nodejs#43992
- Loading branch information
Showing
13 changed files
with
148 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
'use strict'; | ||
const assert = require('assert'); | ||
const v8 = require('v8'); | ||
|
||
function allocateUntilCrash(resourceLimits) { | ||
const array = []; | ||
while (true) { | ||
const usedMB = v8.getHeapStatistics().used_heap_size / 1024 / 1024; | ||
const maxReservedSize = resourceLimits.maxOldGenerationSizeMb + | ||
resourceLimits.maxYoungGenerationSizeMb; | ||
assert(usedMB < maxReservedSize); | ||
|
||
let seenSpaces = 0; | ||
for (const { space_name, space_size } of v8.getHeapSpaceStatistics()) { | ||
if (space_name === 'new_space') { | ||
seenSpaces++; | ||
assert( | ||
space_size / 1024 / 1024 < resourceLimits.maxYoungGenerationSizeMb * 2); | ||
} else if (space_name === 'old_space') { | ||
seenSpaces++; | ||
assert(space_size / 1024 / 1024 < resourceLimits.maxOldGenerationSizeMb); | ||
} else if (space_name === 'code_space') { | ||
seenSpaces++; | ||
assert(space_size / 1024 / 1024 < resourceLimits.codeRangeSizeMb); | ||
} | ||
} | ||
assert.strictEqual(seenSpaces, 3); | ||
|
||
for (let i = 0; i < 100; i++) | ||
array.push([array]); | ||
} | ||
} | ||
|
||
module.exports = { allocateUntilCrash }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const { allocateUntilCrash } = require('../common/allocate-and-check-limits'); | ||
const resourceLimits = JSON.parse(process.argv[2]); | ||
allocateUntilCrash(resourceLimits); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use strict'; | ||
|
||
require('../common'); | ||
const assert = require('assert'); | ||
const fixtures = require('../common/fixtures'); | ||
const fixture = fixtures.path('thread-max-old-space-size.js'); | ||
const { spawnSync } = require('child_process'); | ||
const resourceLimits = { | ||
maxOldGenerationSizeMb: 16, | ||
maxYoungGenerationSizeMb: 4, | ||
// Set codeRangeSizeMb really high to effectively ignore it. | ||
codeRangeSizeMb: 999999, | ||
stackSizeMb: 4, | ||
}; | ||
const res = spawnSync(process.execPath, [`--stack-size=${1024 * resourceLimits.stackSizeMb}`, `--thread-max-old-space-size=${resourceLimits.maxOldGenerationSizeMb}`, `--max-semi-space-size=${resourceLimits.maxYoungGenerationSizeMb / 2}`, fixture, JSON.stringify(resourceLimits)]); | ||
assert(res.stderr.toString('utf8').includes('Allocation failed - JavaScript heap out of memory')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Flags: --thread-max-old-space-size=1024 | ||
'use strict'; | ||
const common = require('../common'); | ||
const assert = require('assert'); | ||
const { Worker, resourceLimits } = require('worker_threads'); | ||
const { allocateUntilCrash } = require('../common/allocate-and-check-limits'); | ||
|
||
const testResourceLimits = { | ||
maxOldGenerationSizeMb: 16, | ||
maxYoungGenerationSizeMb: 4, | ||
codeRangeSizeMb: 16, | ||
stackSizeMb: 1, | ||
}; | ||
|
||
// Do not use isMainThread so that this test itself can be run inside a Worker. | ||
if (!process.env.HAS_STARTED_WORKER) { | ||
process.env.HAS_STARTED_WORKER = 1; | ||
const w = new Worker(__filename, { resourceLimits: testResourceLimits }); | ||
assert.deepStrictEqual(w.resourceLimits, testResourceLimits); | ||
w.on('exit', common.mustCall((code) => { | ||
assert.strictEqual(code, 1); | ||
assert.deepStrictEqual(w.resourceLimits, {}); | ||
})); | ||
w.on('error', common.expectsError({ | ||
code: 'ERR_WORKER_OUT_OF_MEMORY', | ||
message: 'Worker terminated due to reaching memory limit: ' + | ||
'JS heap out of memory' | ||
})); | ||
return; | ||
} | ||
|
||
assert.deepStrictEqual(resourceLimits, testResourceLimits); | ||
// resourceLimits should be used; --thread-max-old-space-size should only | ||
// affect the main thread. | ||
allocateUntilCrash(resourceLimits); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters