Skip to content

Commit

Permalink
Improve memory usage dumper
Browse files Browse the repository at this point in the history
Write to data file from node
Execute gle after profiling
  • Loading branch information
Sannis committed Jun 5, 2012
1 parent 467a1d6 commit fdabeff
Showing 1 changed file with 120 additions and 41 deletions.
161 changes: 120 additions & 41 deletions tools/memory-usage-dump.js
Expand Up @@ -8,21 +8,28 @@ See license text in LICENSE file

var
// Require modules
fs = require("fs"),
mysql = require("../"),
async = require("async"),
helper = require("./memory-helper"),
// Load configuration
cfg = require("../tests/config"),
// Parameters
timeLimitInSec = 10*60*60,
forceGc = false,
timeLimitInSec = 10 * 60,
gcLevel = 0,
pauseBetweenOperationsInMs = 1,
logMemoryUsageIntervalInMs = 400,
logMemoryUsageInterval = null,
// Start time
startHrTime = [0, 0];

function logMemoryUsage() {
dumpMemoryUsageIntervalInMs = 200,
dumpMemoryUsageInterval = null,
drawMemoryUsageGraphIntervalInMs = 60*1000,
drawMemoryUsageGraphInterval = null,
// Start time
startHrTime = [0, 0],
// Other
filenameResult = '',
filenameData = '',
dataFd = null;

function dumpMemoryUsage() {
var
currentHrTime = process.hrtime(),
timeDelta = '',
Expand All @@ -35,7 +42,7 @@ function logMemoryUsage() {
timeDelta = (currentHrTime[0] - startHrTime[0] - 1) + (currentHrTime[1] - startHrTime[1] + 1e9)/1e9;
}

console.log(timeDelta + '\t' + memoryUsage.rss/Mb + '\t' + memoryUsage.heapUsed/Mb + '\t' + memoryUsage.heapTotal/Mb);
fs.writeSync(dataFd, timeDelta + '\t' + memoryUsage.rss/Mb + '\t' + memoryUsage.heapUsed/Mb + '\t' + memoryUsage.heapTotal/Mb + "\n");
}

function performOperation(callback) {
Expand All @@ -59,47 +66,119 @@ function performOperation(callback) {
});
}

// Parse program arguments
params = process.argv.splice(2);

var gcLevelFound = false;
params.forEach(function (param) {
if (param.slice(0, 5) === "--gc=") {
gcLevel = param.slice(5);
} else if (param === '--gc') {
gcLevelFound = true;
} else if (gcLevelFound) {
gcLevel = param;
gcLevelFound = false;
}
});

gcLevel = parseInt(gcLevel, 10);

var myGc = function () {};
if (gcLevel > 0) {
myGc = gc;
}
if (gcLevel > 1) {
myGc = helper.heavyGc;
}

filenameData = "memory-usage-dump.dat";
filenameResult = "memory-usage-gc-" + gcLevel + ".png";

// Main program
console.log("time\tRSS\theapUsed\theapTotal");
openDataFile();

startHrTime = process.hrtime();
logMemoryUsage();
function openDataFile() {
console.log("Opening data file for writing...");

if (logMemoryUsageIntervalInMs > 0) {
logMemoryUsageInterval = setInterval(logMemoryUsage, logMemoryUsageIntervalInMs);
fs.open(__dirname + "/" + filenameData, "w", function (error, fd) {
if (error) throw error;

dataFd = fd;

process.nextTick(dumpMemoryUsageProfile);
});
}

async.whilst(
function () {
var currentHrTime = process.hrtime();
function dumpMemoryUsageProfile() {
console.log("Start writing...");

return (currentHrTime[0] - startHrTime[0]) < timeLimitInSec;
},
function (callback) {
performOperation(function () {
if (forceGc) {
helper.heavyGc();
}
// Write data table header to file
fs.writeSync(dataFd, "time\tRSS\theapUsed\theapTotal\n");

// Start timer, save initial memory usage
startHrTime = process.hrtime();
if (dumpMemoryUsageIntervalInMs > 0) {
dumpMemoryUsageInterval = setInterval(dumpMemoryUsage, dumpMemoryUsageIntervalInMs);
}
dumpMemoryUsage();
if (drawMemoryUsageGraphIntervalInMs > 0) {
drawMemoryUsageGraphInterval = setInterval(drawMemoryUsageGraph, drawMemoryUsageGraphIntervalInMs);
}

if (logMemoryUsageIntervalInMs == 0) {
logMemoryUsage();
// Start async operations
async.whilst(
function () {
var currentHrTime = process.hrtime();

return (currentHrTime[0] - startHrTime[0]) < timeLimitInSec;
},
function (callback) {
performOperation(function () {
myGc();

if (dumpMemoryUsageIntervalInMs === 0) {
dumpMemoryUsage();
}

if (pauseBetweenOperationsInMs > 0) {
setTimeout(callback, pauseBetweenOperationsInMs);
} else {
process.nextTick(callback);
}
});
},
function (error) {
if (error) throw error;

// All ok
if (dumpMemoryUsageInterval) {
clearInterval(dumpMemoryUsageInterval);
}
if (drawMemoryUsageGraphInterval) {
clearInterval(drawMemoryUsageGraphInterval);
}

fs.close(dataFd, function (error) {
if (error) throw error;

console.log("Draw graph...");
drawMemoryUsageGraph(function () {
console.log("Done.");
});
});
}
);
}

function drawMemoryUsageGraph(callback) {
require("child_process").exec(
"gle -output " + __dirname + "/" + filenameResult + " " + __dirname + "/memory-usage-dump.gle",
function (error) {
if (error) throw error;

if (pauseBetweenOperationsInMs > 0) {
setTimeout(callback, pauseBetweenOperationsInMs);
} else {
if (typeof callback === "function") {
process.nextTick(callback);
}
});
},
function (error) {
if (error) throw error;

// All ok
if (logMemoryUsageInterval) {
clearInterval(logMemoryUsageInterval);
}

process.exit(0);
}
);
);
}

0 comments on commit fdabeff

Please sign in to comment.