Skip to content

Instantly share code, notes, and snippets.

@IdrisAkintobi
Created April 30, 2025 08:46
Show Gist options
  • Save IdrisAkintobi/8063fc1b1acb2148dd9523a0b0792ed1 to your computer and use it in GitHub Desktop.
Save IdrisAkintobi/8063fc1b1acb2148dd9523a0b0792ed1 to your computer and use it in GitHub Desktop.
Javascript function to create heapsnapshot and heapprofile
'use strict';
const v8Profiler = require('v8-profiler-next');
const fs = require('fs');
const fsPromises = require('fs').promises;
const { join } = require('path');
const appLogger = require('../logger');
const wait = (timeMS) => new Promise((res) => setTimeout(res, timeMS));
const snapshotsFolder = join(__dirname, '..', 'heap-snapshots');
// Use synchronous methods for directory check and creation
if (!fs.existsSync(snapshotsFolder)) {
fs.mkdirSync(snapshotsFolder);
}
const THIRTY_SECONDS_IN_MILLISECONDS = 30_000;
/**
* Takes a heap snapshot with minimal impact on the main thread
* @returns {Promise<void>} Path to the saved snapshot file
*/
async function createHeapSnapshot() {
try {
appLogger.info('snapshotHeap recording started...');
const filename = join(snapshotsFolder, `${Date.now().toString()}.heapsnapshot`);
// Take the snapshot - This operation blocks the main thread.
const snapshot = v8Profiler.takeSnapshot();
const transform = snapshot.export();
const writeStream = fs.createWriteStream(filename, { flags: 'w' });
transform.pipe(writeStream);
transform.on('finish', () => {
snapshot.delete();
appLogger.info(`snapshot heap recording completed: ${filename}`);
});
transform.on('error', (err) => {
appLogger.withError(err).error('error taking heap snapshot');
});
} catch (err) {
appLogger.withError(err).error('error in creating heap snapshot');
}
}
/**
* Creates a heap profile over a specified duration
* @param {number} timeMs - Duration in milliseconds to profile
* @returns {Promise<void>} Path to the saved profile file
*/
async function createHeapProfile(timeMs = THIRTY_SECONDS_IN_MILLISECONDS) {
try {
appLogger.info(`heap profiling for ${timeMs / 1000} recording started...`);
const filename = join(snapshotsFolder, `${Date.now().toString()}.heapprofile`);
// Start profiling
v8Profiler.startSamplingHeapProfiling();
// Wait for specified duration
await wait(timeMs);
// Stop profiling and save results
const profile = v8Profiler.stopSamplingHeapProfiling();
try {
await fsPromises.writeFile(filename, JSON.stringify(profile));
appLogger.info(`heap profile recording completed: ${filename}`);
} catch (writeErr) {
appLogger.withError(writeErr).error('error writing heap profile to file');
}
} catch (err) {
appLogger.withError(err).error('error in creating heap profile');
}
}
module.exports = {
createHeapSnapshot,
createHeapProfile,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment