Skip to content

Instantly share code, notes, and snippets.

@thejoshwolfe
Created April 17, 2017 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thejoshwolfe/4a37e5c811ec6a38e1a80ffc4c9eb9ce to your computer and use it in GitHub Desktop.
Save thejoshwolfe/4a37e5c811ec6a38e1a80ffc4c9eb9ce to your computer and use it in GitHub Desktop.
testing if abandoning a zlib inflate stream causes a memory leak
var zlib = require("zlib");
var Transform = require("stream").Transform;
var BufferList = require("bl");
function createDeflatedBuffer(size, cb) {
var inputBuffer = new Buffer(size);
for (var i = 0; i < size; i++) {
inputBuffer[i] = Math.floor(Math.random() * 0x100);
}
var deflater = zlib.createDeflateRaw();
deflater.write(inputBuffer);
deflater.end();
deflater.pipe(BufferList(cb));
}
function countInflateChunks(buffer, callback) {
var count = 0;
var chunkCounter = new Transform();
chunkCounter._transform = function(chunk, encoding, cb) {
count++;
cb(null, chunk);
};
chunkCounter.on("finish", function() {
callback(null, count);
});
chunkCounter.on("data", function() {});
var inflater = zlib.createInflateRaw();
inflater.pipe(chunkCounter);
inflater.write(buffer);
inflater.end();
}
var testBuffer;
function findTestBuffer() {
var size = 0;
iterate();
function iterate() {
size += 0x1000;
createDeflatedBuffer(size, function(err, buffer) {
if (err) throw err;
countInflateChunks(buffer, function(err, chunkCount) {
if (err) throw err;
if (chunkCount < 3) {
iterate();
} else {
console.log("test buffer size: 0x" + size.toString(16));
testBuffer = buffer;
console.log("starting memory leak tests");
makeMemoryLeaks();
}
});
});
}
}
var testCount = 0;
function makeMemoryLeaks() {
testCount++;
if (/^\d0000+$/.test(testCount.toString())) console.log("test: " + testCount);
var inflater = zlib.createInflateRaw();
var abandoner = new Transform();
abandoner._transform = function(chunk, encoding, cb) {
inflater.unpipe(abandoner);
abandoner.emit("error", new Error());
};
abandoner.on("error", function() {
makeMemoryLeaks();
});
inflater.pipe(abandoner);
inflater.write(testBuffer);
inflater.end();
}
console.log("finding sufficiently large size...");
findTestBuffer();
$ node a.js
finding sufficiently large size...
test buffer size: 0x9000
starting memory leak tests
test: 10000
test: 20000
test: 30000
test: 40000
test: 50000
test: 60000
test: 70000
test: 80000
test: 90000
test: 100000
test: 200000
test: 300000
test: 400000
test: 500000
test: 600000
test: 700000
test: 800000
test: 900000
test: 1000000
test: 2000000
test: 3000000
test: 4000000
test: 5000000
test: 6000000
test: 7000000
test: 8000000
test: 9000000
test: 10000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment