Skip to content

Commit 7edcda4

Browse files
committed
- bump to 1.0.10
- Use gc-stats to calculate when to make a OoM heapdumo instead of process.memoryUsage() as this memory information (heapTotal) is growing over time, which is not what was expected while developing. - Stringify gc-stats output, so it runs over only 1 line.
1 parent 6cf281d commit 7edcda4

File tree

8 files changed

+26
-23
lines changed

8 files changed

+26
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
11-17-2017 - Paul Rütter
2+
- 1.0.10 - Use gc-stats to calculate when to make a OoM heapdumo instead of process.memoryUsage() as this memory information (heapTotal) is growing over time, which is not expected.
3+
- Stringify gc-stats output, so it runs over only 1 line.
4+
15
06-10-2017 - Paul Rütter
26
- 1.0.9 - Handle exit codes better and reject promise if so.
37

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ It can also create heapdumps and CPU profiles on request like 'v8-profiler', but
66
Tested on Node.js 8.x, but should also work fine using Node.js 6.3 upwards (According to: https://chromedevtools.github.io/devtools-protocol/v8/).
77

88
# Why?
9-
When running nodejs processes in a low memory environment, every out of memory that occurs is interesting.
9+
When running nodejs processes in a low memory environment, every out of memory that occurs is interesting.
1010
To figure out why a process went out of memory, a heap snapshot (e.g. heapdump) can help a lot.
1111
This module creates a heap snapshot right before a suspected out of memory error occurs.
1212
It shows what the heap was filled with right before the out of memory error occured.
1313

1414
There are several modules around which can create heapdumps (v8-profiler, node-heapdump), but these run in the same process as the one going out of memory. Often, creating heapdump won't work when the node process is already struggling.
15-
This module creates the heap snapshot from a separate process, which solves this issue.
15+
This module creates the heap snapshot from a separate process, which solves this issue.
1616

1717
# What?
1818
It uses 'gc-stats' to determine when an out of memory error is about to occur and then fires up a new process which uses 'chrome-remote-interface' to connect with the DevTools protocol (https://chromedevtools.github.io/devtools-protocol/v8/) of the calling process. That process uses HeapProfiler to actually create the heapdump and then exits.
@@ -31,7 +31,7 @@ Just add the following snippet to your node process.
3131
```javascript
3232
let path = require('path');
3333
require('node-oom-heapdump')({
34-
threshold: 90,
34+
threshold: 70,
3535
path: path.resolve(__dirname, 'my_heapdump')
3636
});
3737
```
@@ -48,7 +48,7 @@ These might impact performance though.
4848

4949
# Options
5050
* heapdumpOnOOM - boolean whether to create a heapdump when an out of memory occurs. Default true.
51-
* threshold - integer between 0 and 100 (%) which determines when to make the heapdump. When the used heapSize exceeds the threshold, a heapdump is made. This value can be tuned depending on your configuration; if memory usage is very volatile, a lower value might make more sense. Default is 90.
51+
* threshold - integer between 0 and 100 (%) which determines when to make the heapdump. When the used heapSize exceeds the threshold, a heapdump is made. This value can be tuned depending on your configuration; if memory usage is very volatile, a lower value might make more sense. Default is 70.
5252
* path - the path where the heapdump ends up when an out of memory error occurs. '.heapsnapshot' is automatically appended. Defaults to this modules' directory.
5353
* addTimestamp - add a timestamp to the out of memory heapdump filename, to make it unique. Default is false.
5454
* limit - optionally, specify a limit to how many heapdumps will be created when being above the threshold. Default is 3.
@@ -71,7 +71,7 @@ let nodeOomHeapdump = require("node-oom-heapdump")({
7171
*/
7272
nodeOomHeapdump.createHeapSnapshot("myheapsnapshotpath").then((snapshotPath) => {
7373
// do something with heap snapshot
74-
74+
7575
// and delete again from disk
7676
nodeOomHeapdump.deleteHeapSnapshot(snapshotPath);
7777
}).catch((err) => {
@@ -85,7 +85,7 @@ nodeOomHeapdump.deleteAllHeapSnapshots();
8585

8686
/**
8787
* Deletes a particular snapshot from disk
88-
* @param {String} snapshotPath - path of the heap snapshot to delete
88+
* @param {String} snapshotPath - path of the heap snapshot to delete
8989
* @return {Promise}
9090
*/
9191
nodeOomHeapdump.deleteHeapSnapshot(snapshotPath);
@@ -98,7 +98,7 @@ nodeOomHeapdump.deleteHeapSnapshot(snapshotPath);
9898
*/
9999
nodeOomHeapdump.createCpuProfile("mycpuprofilepath", 10000).then((cpuProfilePath) => {
100100
// do something with CPU profile
101-
101+
102102
// and delete again from disk
103103
nodeOomHeapdump.deleteCpuProfile(cpuProfilePath);
104104
}).catch((err) => {

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class NodeOomHeapdumpAPI {
3737

3838
/**
3939
* Deletes a particular snapshot from disk
40-
* @param {String} snapshotPath - path of the heap snapshot to delete
40+
* @param {String} snapshotPath - path of the heap snapshot to delete
4141
* @return {Promise}
4242
*/
4343
deleteHeapSnapshot(snapshotPath) {
@@ -82,7 +82,7 @@ function parseOptions(options) {
8282
options.heapdumpOnOOM = true;
8383
}
8484
if (options.threshold === undefined) {
85-
options.threshold = 90;
85+
options.threshold = 70;
8686
} else {
8787
options.threshold = parseInt(options.threshold);
8888
}

lib/cpuProfileWorker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ writeStream.on('error', (err) => {
2020

2121
CDP({
2222
host: 'localhost',
23-
port: devToolsPort,
23+
port: devToolsPort
2424
}, (debugInstance) => {
2525
let cpuProfiler = debugInstance.Profiler;
2626
cpuProfiler.enable();

lib/heapdumpWorker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ writeStream.on('error', (err) => {
2020

2121
CDP({
2222
host: 'localhost',
23-
port: devToolsPort,
23+
port: devToolsPort
2424
}, (debugInstance) => {
2525
debugInstance.Debugger.enable();
2626
debugInstance.Debugger.pause();
@@ -32,7 +32,7 @@ CDP({
3232
writeStream.write(evt.chunk);
3333
});
3434
heapProfiler.takeHeapSnapshot({
35-
reportProgress: false,
35+
reportProgress: false
3636
}, function () {
3737
heapProfiler.disable();
3838
writeStream.end();

lib/index.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ class NodeOomHeapDumpImpl {
2121
gcStats.on('stats', (stats) => {
2222
// gctype 2 is a Full GC (Mark/Sweep/Compact)
2323
if (stats.gctype === 2 && !this._busy) {
24-
let memoryUsage = process.memoryUsage();
25-
var memoryUsagePercentage = Math.round((memoryUsage.heapUsed / memoryUsage.heapTotal) * 100);
24+
let memoryUsagePercentage = Math.round((stats.after.usedHeapSize / stats.after.heapSizeLimit) * 100);
2625
if (memoryUsagePercentage > this._opts.threshold) {
2726
if (this._count < this._opts.limit) {
2827
// this is a full GC and the used heap size is using more than x% of the assigned heap space limit
29-
console.warn('OoM is imminent: Full GC (Mark/Sweep/Compact) complete and still more than %s% (%s%) of the heap is used. Creating heapdump now. GC stats: ', this._opts.threshold, Math.round(memoryUsagePercentage), stats);
28+
console.warn('OoM is imminent: Full GC (Mark/Sweep/Compact) complete and still more than %s% (%s%) of the heap is used. Creating heapdump now. GC stats: ', this._opts.threshold, Math.round(memoryUsagePercentage), JSON.stringify(stats));
3029

3130
this.createHeapSnapshot(this._opts.path, "OoM");
3231

@@ -158,7 +157,7 @@ class NodeOomHeapDumpImpl {
158157

159158
/**
160159
* Deletes a particular snapshot from disk
161-
* @param {String} snapshotPath - path of the heap snapshot to delete
160+
* @param {String} snapshotPath - path of the heap snapshot to delete
162161
* @return {Promise}
163162
*/
164163
deleteHeapSnapshot(snapshotPath) {
@@ -178,7 +177,7 @@ class NodeOomHeapDumpImpl {
178177

179178
/**
180179
* Deletes a particular CPU profile from disk
181-
* @param {String} cpuProfilePath - path of the CPU profile to delete
180+
* @param {String} cpuProfilePath - path of the CPU profile to delete
182181
* @return {Promise}
183182
*/
184183
deleteCpuProfile(cpuProfilePath) {
@@ -187,7 +186,7 @@ class NodeOomHeapDumpImpl {
187186

188187
/**
189188
* Deletes a given CPU profile or heapsnapshot from disk
190-
* @param {String} path - path to the file to delete
189+
* @param {String} path - path to the file to delete
191190
* @return {Promise}
192191
*/
193192
_deleteFile(path) {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "node-oom-heapdump",
3-
"version": "1.0.9",
3+
"version": "1.0.10",
44
"description": "Create a V8 heap snapshot right before an \"Out of Memory\" error occurs, or create a heap snapshot on request.",
55
"main": "index.js",
66
"scripts": {
7-
"test": "node --max_old_space_size=60 --optimize_for_size --always_compact --inspect tests\\oom_app.js"
7+
"test": "node --max_old_space_size=80 --optimize_for_size --always_compact --inspect tests\\oom_app.js"
88
},
99
"repository": {
1010
"type": "git",

tests/oom_app.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
let path = require('path');
2-
2+
33
let oom = require("../index.js")({
4-
threshold: 90,
4+
threshold: 70,
55
path: path.resolve(__dirname, 'my_heapdump'),
66
heapdumpOnOOM: true,
7-
limit: 2,
7+
limit: 1,
88
addTimestamp: false
99
});
1010

0 commit comments

Comments
 (0)