This repository has been archived by the owner on Sep 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 98
Memory Leaks #73
Comments
Small data point here: By using the const lz4 = require(".");
const opts = {useJS: true};
for (let i = 0; i < 10000; i++) {
let a = lz4.decode(lz4.encode("0123456789", opts), opts); // memory leak!!
if (i % 100 == 0) {
let res = process.memoryUsage();
console.log(
"mem:",
res.external.toLocaleString(),
res.heapTotal.toLocaleString(),
res.heapUsed.toLocaleString(),
res.rss.toLocaleString()
);
}
} |
I extended the test tool a bit as I found the initial output very scary, but after reviewing the binding code here and playing with some theories I think there is no real leak here -- rather what happens is that NodeJS/V8 figure out that running a GC isn't needed in this example. The extended test code: try {
const gc = require('gc-stats')();
gc.on('stats', stats => {
const { gctype, pauseMS, diff: {usedHeapSize}} = stats;
console.log(`gc ${gctype}: ${usedHeapSize}\t(${pauseMS}ms)`);
});
} catch (err) {
// Fine.
}
const lz4 = require('.');
const opts = {useJS: process.env.USE_JS === 'true'};
const iterations = Number(process.argv[2]) || 10000;
const forceGc = process.env.FORCE_GC === 'true';
const taskDelay = typeof process.env.TASK_DELAY !== undefined ? Number(process.env.TASK_DELAY) : undefined;
function runGc() {
// Run with --expose-gc to make this available
if (global.gc) {
global.gc();
}
}
function printStats(prefix) {
let res = process.memoryUsage();
console.log(
`mem (${prefix}):\t`,
[
res.external.toLocaleString(),
res.heapTotal.toLocaleString(),
res.heapUsed.toLocaleString(),
res.rss.toLocaleString(),
res.arrayBuffers.toLocaleString(),
].map(s => s.padStart(12)).join('\t')
);
}
function delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
function test() {
let encoded = lz4.encode('0123456789', opts);
let decoded = lz4.decode(encoded, opts); // memory leak?
}
async function main(what, iterations) {
let iteration = 1;
do {
console.log(`Running iteration ${iteration}`);
runGc();
printStats('initial');
for (let i = 0; i < iterations; i++) {
// Run the code-under-test
what();
// Do some statistics
if (i % 100 == 0) {
printStats('before');
if (forceGc) {
runGc();
printStats('after');
}
if (typeof taskDelay !== 'undefined') {
await delay(taskDelay);
}
}
}
printStats('final');
await delay(5000);
} while (iteration++);
}
main(test, iterations); Some things to try:
Basically: the leak here is a leak because the test loop is so tight that NodeJS/V8 simply don't run a GC. |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
The following code generates memory leaks and eventually crashes.
I've tried it with node v11.10.0 and v10.15.1LTS on both Windows 7 SP1 and CentOS 7.
Any ideas?
The text was updated successfully, but these errors were encountered: