-
-
Save thejoshwolfe/4a37e5c811ec6a38e1a80ffc4c9eb9ce to your computer and use it in GitHub Desktop.
testing if abandoning a zlib inflate stream causes a memory leak
This file contains hidden or 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
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(); |
This file contains hidden or 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
$ 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