Skip to content

Commit 1586c11

Browse files
joyeecheungrichardlau
authored andcommitted
test: add checkIfCollectable to test/common/gc.js
PR-URL: #49671 Backport-PR-URL: #51004 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
1 parent 7552de6 commit 1586c11

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

test/common/gc.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
// TODO(joyeecheung): merge ongc.js and gcUntil from common/index.js
4+
// into this.
5+
6+
// This function can be used to check if an object factor leaks or not,
7+
// but it needs to be used with care:
8+
// 1. The test should be set up with an ideally small
9+
// --max-old-space-size or --max-heap-size, which combined with
10+
// the maxCount parameter can reproduce a leak of the objects
11+
// created by fn().
12+
// 2. This works under the assumption that if *none* of the objects
13+
// created by fn() can be garbage-collected, the test would crash due
14+
// to OOM.
15+
// 3. If *any* of the objects created by fn() can be garbage-collected,
16+
// it is considered leak-free. The FinalizationRegistry is used to
17+
// terminate the test early once we detect any of the object is
18+
// garbage-collected to make the test less prone to false positives.
19+
// This may be especially important for memory management relying on
20+
// emphemeron GC which can be inefficient to deal with extremely fast
21+
// heap growth.
22+
// Note that this can still produce false positives. When the test using
23+
// this function still crashes due to OOM, inspect the heap to confirm
24+
// if a leak is present (e.g. using heap snapshots).
25+
// The generateSnapshotAt parameter can be used to specify a count
26+
// interval to create the heap snapshot which may enforce a more thorough GC.
27+
// This can be tried for code paths that require it for the GC to catch up
28+
// with heap growth. However this type of forced GC can be in conflict with
29+
// other logic in V8 such as bytecode aging, and it can slow down the test
30+
// significantly, so it should be used scarcely and only as a last resort.
31+
async function checkIfCollectable(
32+
fn, maxCount = 4096, generateSnapshotAt = Infinity, logEvery = 128) {
33+
let anyFinalized = false;
34+
let count = 0;
35+
36+
const f = new FinalizationRegistry(() => {
37+
anyFinalized = true;
38+
});
39+
40+
async function createObject() {
41+
const obj = await fn();
42+
f.register(obj);
43+
if (count++ < maxCount && !anyFinalized) {
44+
setImmediate(createObject, 1);
45+
}
46+
// This can force a more thorough GC, but can slow the test down
47+
// significantly in a big heap. Use it with care.
48+
if (count % generateSnapshotAt === 0) {
49+
// XXX(joyeecheung): This itself can consume a bit of JS heap memory,
50+
// but the other alternative writeHeapSnapshot can run into disk space
51+
// not enough problems in the CI & be slower depending on file system.
52+
// Just do this for now as long as it works and only invent some
53+
// internal voodoo when we absolutely have no other choice.
54+
require('v8').getHeapSnapshot().pause().read();
55+
console.log(`Generated heap snapshot at ${count}`);
56+
}
57+
if (count % logEvery === 0) {
58+
console.log(`Created ${count} objects`);
59+
}
60+
if (anyFinalized) {
61+
console.log(`Found finalized object at ${count}, stop testing`);
62+
}
63+
}
64+
65+
createObject();
66+
}
67+
68+
module.exports = {
69+
checkIfCollectable,
70+
};

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy