node-oom-heapdump 2.2.0 → 3.0.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +2 -0
- package/CHANGELOG.md +11 -0
- package/README.md +15 -30
- package/build/node_oom_heapdump_native.vcxproj +30 -13
- package/index.js +1 -2
- package/lib/index.js +0 -41
- package/package.json +7 -18
- package/.github/workflows/publish-native-assets-to-github-releases.yml +0 -37
- package/binding.gyp +0 -10
- package/lib/node_oom_heapdump_native.cc +0 -99
- package/tests/index.js +0 -27
- package/tests/long_running_process.js +0 -27
- package/tests/long_running_process_cpu.js +0 -35
- package/tests/oom_app.js +0 -22
package/.travis.yml
CHANGED
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
09-02-2022 Paul Rütter
|
2
|
+
- 3.0.0
|
3
|
+
- Updated dependencies to resolve https://github.com/blueconic/node-oom-heapdump/issues/19
|
4
|
+
- Removed `gc-stats` as it was not used a lot anymore (breaking change) and contained security issues.
|
5
|
+
- Removed creating heapdumps on out of memory, as this is superseeded by native node functionality.
|
6
|
+
- Remove unused dependencies and native code.
|
7
|
+
|
8
|
+
21-12-2020 Paul Rütter
|
9
|
+
- 2.2.0
|
10
|
+
- Updated ini
|
11
|
+
|
1
12
|
12-10-2020 Paul Rütter
|
2
13
|
- 2.1.0
|
3
14
|
- Added Node 14 support
|
package/README.md
CHANGED
@@ -1,34 +1,29 @@
|
|
1
1
|
[](https://travis-ci.org/blueconic/node-oom-heapdump)
|
2
2
|
|
3
3
|
# node-oom-heapdump
|
4
|
-
Node module
|
4
|
+
Node module that can create heapdumps and CPU profiles on request like 'v8-profiler', but does this off-process so it doesn't interfere with execution of the main process.
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
Tested on Node.js 7.x, 8.x, 9.x, 10.x, 11.x, 12.x, 13.x and 14.x.
|
6
|
+
Tested on Node.js 7.x, 8.x, 9.x, 10.x, 11.x, 12.x, 13.x, 14.x and 16.x.
|
9
7
|
No support for Node.js < 7.0 at the moment (although this can be fixed if needed).
|
10
8
|
|
11
9
|
Also comes with prebuilt binaries (hosted on Github releases), thanks to Stuart Miller (https://github.com/spmiller).
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
It shows what the heap was filled with right before the out of memory error occured and can be opened with Chrome DevTools (Memory tab).
|
11
|
+
## Node.js 14.18.x and higher
|
12
|
+
https://github.com/nodejs/node/pull/33010 landed in Node.js 14.18.0, which makes this module no longer needed for heapdumps on out of memory.
|
13
|
+
One can use the `--heapsnapshot-near-heap-limit` Node.js CLI option as an native alternative.
|
14
|
+
See https://nodejs.org/dist/latest-v14.x/docs/api/cli.html#cli_heapsnapshot_near_heap_limit_max_count.
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
Also, these modules are not able to create a heapdump when an out of memory occurs.
|
16
|
+
For Node versions older than 14, use the `2.2.0` release, where this functionality is still present (not maintained anymore).
|
17
|
+
For Node versions 14 and up, use `--heapsnapshot-near-heap-limit` for out-of-memory heapdumps. This functionality has been removed from `3.0.0`.
|
22
18
|
|
23
|
-
|
24
|
-
Based on the work of 'trevnorris' (https://github.com/trevnorris/node-ofe/), this module uses 'isolate.SetOOMErrorHandler' (https://v8docs.nodesource.com/node-8.9/d5/dda/classv8_1_1_isolate.html#a08fd4087f39c33b4ac1c20ad953ce4e3) of the V8 engine, and then creates a heapdump when an actual Out of Memory occurs. To make this happen, a native C++ add-on is used.
|
25
|
-
Node-gyp is needed to compile this add-on.
|
19
|
+
One can still use the API of this module to create CPU profiles and heapdumps on request
|
26
20
|
|
27
|
-
|
28
|
-
|
21
|
+
# Why?
|
22
|
+
There are several modules around which can create heapdumps (v8-profiler, node-heapdump), although this module creates the heap snapshot from a separate process which performs better and doesn't affect the main event loop.
|
29
23
|
|
30
|
-
#
|
31
|
-
|
24
|
+
# What?
|
25
|
+
When creating a heapdump of CPU profile on request, the DevTools protocol is used to create these files (no native add-on needed).
|
26
|
+
The --inspect node.js flag is needed to make this work (which is validated on startup).
|
32
27
|
|
33
28
|
# Usage
|
34
29
|
|
@@ -57,20 +52,10 @@ These might impact performance though.
|
|
57
52
|
On Node.js 12.x the latter two flags seem to cause some stability issues (see https://github.com/nodejs/node/issues/27552#issuecomment-542695931). So, if you encounter issues on Node.js 12.x in combination with those flags, please refrain from using these.
|
58
53
|
|
59
54
|
# Options
|
60
|
-
* heapdumpOnOOM - boolean whether to create a heapdump when an out of memory occurs. Default true.
|
61
|
-
* OOMImplementation - Either "NATIVE_HOOK" or "GC_MONITORING".
|
62
|
-
"NATIVE_HOOK" relies on the native v8 hook and makes sure that the heapdump is actually created when the OoM occurs. It's more impacted by the OoMKiller of Unix systems though, when being run in memory restricted environments like Docker.
|
63
|
-
"GC_MONITORING" is the old implementation, which relies on GC monitoring. It's less impacted by OoMKiller, because the 'threshold' parameter determines when to create the heapdump. Use this option when you run into the OoMKiller of the Unix OS. Default is "NATIVE_HOOK".
|
64
|
-
* path - the path where the heapdump ends up when an out of memory error occurs. '.heapsnapshot' is automatically appended. Defaults to this modules' directory.
|
65
|
-
* addTimestamp - add a timestamp to the out of memory heapdump filename, to make it unique. Default is false.
|
66
55
|
* port - optionally, the alternative DevTools protocol port. Defaults to 9229. Should map on the port given to the --inspect arg.
|
67
56
|
|
68
|
-
The following options are only relevant when OOMImplementation="GC_MONITORING".
|
69
|
-
* limit - optionally, specify a limit to how many heapdumps will be created when being above the threshold. Default is 3.
|
70
|
-
* 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.
|
71
|
-
|
72
57
|
# API
|
73
|
-
|
58
|
+
The API for creating heapdumps and CPU profiles on request. See below for the currently available API.
|
74
59
|
|
75
60
|
Notice that you cannot create a heapdump while a CPU profile is being generated and vice versa; an Error will be thrown if this is the case.
|
76
61
|
|
@@ -36,6 +36,7 @@
|
|
36
36
|
<ExecutablePath>$(ExecutablePath);$(MSBuildProjectDirectory)\..\bin\;$(MSBuildProjectDirectory)\..\bin\</ExecutablePath>
|
37
37
|
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
38
38
|
<IntDir>$(Configuration)\obj\$(ProjectName)\</IntDir>
|
39
|
+
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
39
40
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
40
41
|
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
41
42
|
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.node</TargetExt>
|
@@ -47,10 +48,10 @@
|
|
47
48
|
</PropertyGroup>
|
48
49
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
49
50
|
<ClCompile>
|
50
|
-
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\
|
51
|
+
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\include\node;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\src;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\config;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\openssl\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\uv\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\zlib;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\v8\include;..\node_modules\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
52
|
+
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
51
53
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
52
54
|
<BufferSecurityCheck>true</BufferSecurityCheck>
|
53
|
-
<CompileAsWinRT>false</CompileAsWinRT>
|
54
55
|
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
55
56
|
<DisableSpecificWarnings>4351;4355;4800;4251;4275;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
56
57
|
<ExceptionHandling>false</ExceptionHandling>
|
@@ -59,31 +60,38 @@
|
|
59
60
|
<OmitFramePointers>false</OmitFramePointers>
|
60
61
|
<Optimization>Disabled</Optimization>
|
61
62
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
62
|
-
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;DEBUG;_DEBUG;V8_ENABLE_CHECKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
63
|
+
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;_GLIBCXX_USE_CXX11_ABI=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;DEBUG;_DEBUG;V8_ENABLE_CHECKS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
63
64
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
64
65
|
<StringPooling>true</StringPooling>
|
65
66
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
66
67
|
<TreatWarningAsError>false</TreatWarningAsError>
|
67
68
|
<WarningLevel>Level3</WarningLevel>
|
69
|
+
<WholeProgramOptimization>true</WholeProgramOptimization>
|
68
70
|
</ClCompile>
|
71
|
+
<Lib>
|
72
|
+
<AdditionalOptions>/LTCG:INCREMENTAL %(AdditionalOptions)</AdditionalOptions>
|
73
|
+
</Lib>
|
69
74
|
<Link>
|
70
|
-
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;"C:\\Users\\paul.BLUECONIC\\AppData\\Local\\node-gyp\\Cache\\
|
75
|
+
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;"C:\\Users\\paul.BLUECONIC\\AppData\\Local\\node-gyp\\Cache\\16.14.0\\x64\\node.lib"</AdditionalDependencies>
|
76
|
+
<AdditionalOptions>/LTCG:INCREMENTAL %(AdditionalOptions)</AdditionalOptions>
|
77
|
+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
71
78
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
79
|
+
<OptimizeReferences>true</OptimizeReferences>
|
72
80
|
<OutputFile>$(OutDir)$(ProjectName).node</OutputFile>
|
73
81
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
74
82
|
<TargetExt>.node</TargetExt>
|
75
83
|
<TargetMachine>MachineX64</TargetMachine>
|
76
84
|
</Link>
|
77
85
|
<ResourceCompile>
|
78
|
-
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\
|
79
|
-
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;DEBUG;_DEBUG;V8_ENABLE_CHECKS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
86
|
+
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\include\node;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\src;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\config;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\openssl\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\uv\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\zlib;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\v8\include;..\node_modules\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
87
|
+
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;_GLIBCXX_USE_CXX11_ABI=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;DEBUG;_DEBUG;V8_ENABLE_CHECKS;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
80
88
|
</ResourceCompile>
|
81
89
|
</ItemDefinitionGroup>
|
82
90
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
83
91
|
<ClCompile>
|
84
|
-
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\
|
92
|
+
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\include\node;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\src;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\config;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\openssl\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\uv\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\zlib;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\v8\include;..\node_modules\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
93
|
+
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
85
94
|
<BufferSecurityCheck>true</BufferSecurityCheck>
|
86
|
-
<CompileAsWinRT>false</CompileAsWinRT>
|
87
95
|
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
88
96
|
<DisableSpecificWarnings>4351;4355;4800;4251;4275;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
89
97
|
<ExceptionHandling>false</ExceptionHandling>
|
@@ -95,32 +103,41 @@
|
|
95
103
|
<OmitFramePointers>true</OmitFramePointers>
|
96
104
|
<Optimization>Full</Optimization>
|
97
105
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
98
|
-
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
106
|
+
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;_GLIBCXX_USE_CXX11_ABI=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
99
107
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
100
108
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
101
109
|
<StringPooling>true</StringPooling>
|
102
110
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
103
111
|
<TreatWarningAsError>false</TreatWarningAsError>
|
104
112
|
<WarningLevel>Level3</WarningLevel>
|
113
|
+
<WholeProgramOptimization>true</WholeProgramOptimization>
|
105
114
|
</ClCompile>
|
115
|
+
<Lib>
|
116
|
+
<AdditionalOptions>/LTCG:INCREMENTAL %(AdditionalOptions)</AdditionalOptions>
|
117
|
+
</Lib>
|
106
118
|
<Link>
|
107
|
-
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;"C:\\Users\\paul.BLUECONIC\\AppData\\Local\\node-gyp\\Cache\\
|
119
|
+
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;"C:\\Users\\paul.BLUECONIC\\AppData\\Local\\node-gyp\\Cache\\16.14.0\\x64\\node.lib"</AdditionalDependencies>
|
120
|
+
<AdditionalOptions>/LTCG:INCREMENTAL %(AdditionalOptions)</AdditionalOptions>
|
121
|
+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
108
122
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
123
|
+
<OptimizeReferences>true</OptimizeReferences>
|
109
124
|
<OutputFile>$(OutDir)$(ProjectName).node</OutputFile>
|
110
125
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
111
126
|
<TargetExt>.node</TargetExt>
|
112
127
|
<TargetMachine>MachineX64</TargetMachine>
|
113
128
|
</Link>
|
114
129
|
<ResourceCompile>
|
115
|
-
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\
|
116
|
-
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
130
|
+
<AdditionalIncludeDirectories>C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\include\node;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\src;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\config;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\openssl\openssl\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\uv\include;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\zlib;C:\Users\paul.BLUECONIC\AppData\Local\node-gyp\Cache\16.14.0\deps\v8\include;..\node_modules\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
131
|
+
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=node_oom_heapdump_native;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;V8_DEPRECATION_WARNINGS;V8_IMMINENT_DEPRECATION_WARNINGS;_GLIBCXX_USE_CXX11_ABI=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;BUILDING_NODE_EXTENSION;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
117
132
|
</ResourceCompile>
|
118
133
|
</ItemDefinitionGroup>
|
119
134
|
<ItemGroup>
|
120
135
|
<None Include="..\binding.gyp"/>
|
121
136
|
</ItemGroup>
|
122
137
|
<ItemGroup>
|
123
|
-
<ClCompile Include="..\lib\node_oom_heapdump_native.cc"
|
138
|
+
<ClCompile Include="..\lib\node_oom_heapdump_native.cc">
|
139
|
+
<ObjectFileName>$(IntDir)\lib\node_oom_heapdump_native.obj</ObjectFileName>
|
140
|
+
</ClCompile>
|
124
141
|
</ItemGroup>
|
125
142
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
126
143
|
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets"/>
|
package/index.js
CHANGED
@@ -85,8 +85,7 @@ function parseOptions(options) {
|
|
85
85
|
options.heapdumpOnOOM = true;
|
86
86
|
}
|
87
87
|
if (options.OOMImplementation === undefined){
|
88
|
-
// default is the
|
89
|
-
// the other option is "GC_MONITORING", which is the old implementation (which is less impacted by OoMKiller)
|
88
|
+
// default is the implementation, the old one was discarded because it wasn't used
|
90
89
|
options.OOMImplementation = "NATIVE_HOOK";
|
91
90
|
}
|
92
91
|
if (options.port === undefined) {
|
package/lib/index.js
CHANGED
@@ -7,47 +7,6 @@ class NodeOomHeapDumpImpl {
|
|
7
7
|
this._opts = options;
|
8
8
|
this._files = [];
|
9
9
|
this._busy = false;
|
10
|
-
this._count = 0;
|
11
|
-
this._limitReached = false;
|
12
|
-
|
13
|
-
if (this._opts.heapdumpOnOOM) {
|
14
|
-
if (options.OOMImplementation === "NATIVE_HOOK") {
|
15
|
-
require('bindings')('node_oom_heapdump_native.node').call(this._getHeapSnapshotPath(this._opts.path), this._opts.addTimestamp);
|
16
|
-
} else if (options.OOMImplementation === "GC_MONITORING") {
|
17
|
-
this._monitorHeap();
|
18
|
-
}
|
19
|
-
}
|
20
|
-
}
|
21
|
-
|
22
|
-
_monitorHeap() {
|
23
|
-
// see https://www.npmjs.com/package/gc-stats
|
24
|
-
let gcStats = new require('gc-stats')();
|
25
|
-
gcStats.on('stats', (stats) => {
|
26
|
-
// gctype 2 is a Full GC (Mark/Sweep/Compact)
|
27
|
-
if (stats.gctype === 2 && !this._busy) {
|
28
|
-
let memoryUsagePercentage = Math.round((stats.after.usedHeapSize / stats.after.heapSizeLimit) * 100);
|
29
|
-
if (memoryUsagePercentage > this._opts.threshold) {
|
30
|
-
if (this._count < this._opts.limit) {
|
31
|
-
// this is a full GC and the used heap size is using more than x% of the assigned heap space limit
|
32
|
-
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));
|
33
|
-
|
34
|
-
this.createHeapSnapshot(this._opts.path, "OoM");
|
35
|
-
|
36
|
-
// block execution of other code for a while (5 second) to enable snapshot to be created
|
37
|
-
const time = Date.now();
|
38
|
-
let diff = 0;
|
39
|
-
do {
|
40
|
-
diff = Date.now() - time;
|
41
|
-
}
|
42
|
-
while (diff < 5000);
|
43
|
-
} else if (!this._limitReached) {
|
44
|
-
this._limitReached = true;
|
45
|
-
console.warn("OoM heapdump limit reached (%s); no more heapdumps will be created.", this._opts.limit);
|
46
|
-
return;
|
47
|
-
}
|
48
|
-
}
|
49
|
-
}
|
50
|
-
});
|
51
10
|
}
|
52
11
|
|
53
12
|
|
package/package.json
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
{
|
2
2
|
"name": "node-oom-heapdump",
|
3
|
-
"version": "
|
4
|
-
"description": "Create a
|
3
|
+
"version": "3.0.0-beta",
|
4
|
+
"description": "Create a heap snapshot or CPU profile on request, off-process through the DevTools protocol",
|
5
5
|
"main": "index.js",
|
6
6
|
"scripts": {
|
7
|
-
"
|
8
|
-
"
|
9
|
-
"test": "node --max_old_space_size=80 --inspect ./tests/oom_app.js",
|
10
|
-
"dummy": "node -e \"process.exit(0)\""
|
7
|
+
"dummy": "node -e \"process.exit(0)\"",
|
8
|
+
"api-publish-beta": "npm publish --tag beta"
|
11
9
|
},
|
12
10
|
"repository": {
|
13
11
|
"type": "git",
|
14
12
|
"url": "git+https://github.com/blueconic/node-oom-heapdump.git"
|
15
13
|
},
|
16
|
-
"binary": {
|
17
|
-
"module_name": "node_oom_heapdump_native",
|
18
|
-
"module_path": "./build/Release",
|
19
|
-
"host": "https://github.com/blueconic/node-oom-heapdump/releases/download/{version}"
|
20
|
-
},
|
21
14
|
"engines": {
|
22
|
-
"node": ">=
|
15
|
+
"node": ">=14.0.0"
|
23
16
|
},
|
24
17
|
"keywords": [
|
25
18
|
"nodejs",
|
@@ -40,12 +33,8 @@
|
|
40
33
|
"eslint-config-google": "^0.14.0"
|
41
34
|
},
|
42
35
|
"dependencies": {
|
43
|
-
"
|
44
|
-
"chrome-remote-interface": "^0.28.2",
|
45
|
-
"gc-stats": "^1.4.0",
|
46
|
-
"nan": "^2.14.2",
|
47
|
-
"node-pre-gyp": "^0.17.0",
|
36
|
+
"chrome-remote-interface": "^0.31.2",
|
48
37
|
"require-main-filename": "^2.0.0",
|
49
|
-
"ws": "^
|
38
|
+
"ws": "^8.5.0"
|
50
39
|
}
|
51
40
|
}
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# This workflow will prebuild native binaries for supported NodeJS versions, and add them to the Github release that triggered the workflow
|
2
|
-
|
3
|
-
name: Add native binaries to release
|
4
|
-
|
5
|
-
on:
|
6
|
-
release:
|
7
|
-
types: [created]
|
8
|
-
|
9
|
-
jobs:
|
10
|
-
augment-release:
|
11
|
-
runs-on: ${{ matrix.os }}
|
12
|
-
strategy:
|
13
|
-
matrix:
|
14
|
-
node-version: [7.x, 8.x, 9.x, 10.x, 11.x, 12.x, 14.x]
|
15
|
-
os: [ubuntu-latest, macos-latest, windows-latest]
|
16
|
-
steps:
|
17
|
-
- uses: actions/checkout@v2
|
18
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
19
|
-
uses: actions/setup-node@v1
|
20
|
-
with:
|
21
|
-
node-version: ${{ matrix.node-version }}
|
22
|
-
- name: patch node gyp on windows to support Visual Studio 2019
|
23
|
-
if: matrix.os == 'windows-latest'
|
24
|
-
shell: powershell
|
25
|
-
run: |
|
26
|
-
npm install --global node-gyp@5.1.1
|
27
|
-
npm prefix -g | % {npm config set node_gyp "$_\node_modules\node-gyp\bin\node-gyp.js"}
|
28
|
-
- name: build using node-pre-gyp
|
29
|
-
run: |
|
30
|
-
npm install --build-from-source
|
31
|
-
./node_modules/.bin/node-pre-gyp package
|
32
|
-
- name: Upload native binaries for Node ${{ matrix.node-version }} for ${{ matrix.os }}
|
33
|
-
uses: csexton/release-asset-action@v2
|
34
|
-
with:
|
35
|
-
pattern: "build/stage/*.tar.gz"
|
36
|
-
github-token: ${{ secrets.GITHUB_TOKEN }}
|
37
|
-
release-url: ${{ github.event.release.upload_url }}
|
package/binding.gyp
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
#include <nan.h>
|
2
|
-
#include <v8-profiler.h>
|
3
|
-
#include <stdlib.h>
|
4
|
-
#if defined(_WIN32)
|
5
|
-
#include <time.h>
|
6
|
-
#define snprintf _snprintf
|
7
|
-
#else
|
8
|
-
#include <sys/time.h>
|
9
|
-
#endif
|
10
|
-
|
11
|
-
using namespace v8;
|
12
|
-
|
13
|
-
char filename[256];
|
14
|
-
bool addTimestamp;
|
15
|
-
|
16
|
-
class FileOutputStream: public OutputStream {
|
17
|
-
public:
|
18
|
-
FileOutputStream(FILE* stream): stream_(stream) { }
|
19
|
-
virtual int GetChunkSize() {
|
20
|
-
return 65536;
|
21
|
-
}
|
22
|
-
virtual void EndOfStream() { }
|
23
|
-
virtual WriteResult WriteAsciiChunk(char* data, int size) {
|
24
|
-
const size_t len = static_cast<size_t>(size);
|
25
|
-
size_t off = 0;
|
26
|
-
while (off < len && !feof(stream_) && !ferror(stream_))
|
27
|
-
off += fwrite(data + off, 1, len - off, stream_);
|
28
|
-
return off == len ? kContinue : kAbort;
|
29
|
-
}
|
30
|
-
|
31
|
-
private:
|
32
|
-
FILE* stream_;
|
33
|
-
};
|
34
|
-
|
35
|
-
void OnOOMError(const char *location, bool is_heap_oom) {
|
36
|
-
if (addTimestamp) {
|
37
|
-
// Add timestamp to filename
|
38
|
-
time_t rawtime;
|
39
|
-
struct tm* timeinfo;
|
40
|
-
time(&rawtime);
|
41
|
-
timeinfo = localtime(&rawtime);
|
42
|
-
|
43
|
-
char * pch;
|
44
|
-
pch = strstr (filename,".heapsnapshot");
|
45
|
-
strncpy (pch,"",1);
|
46
|
-
strcat (filename, "-%Y%m%dT%H%M%S.heapsnapshot");
|
47
|
-
|
48
|
-
char newFilename[256];
|
49
|
-
strftime(newFilename, sizeof(filename), filename, timeinfo);
|
50
|
-
strcpy(filename, newFilename);
|
51
|
-
}
|
52
|
-
|
53
|
-
fprintf(stderr, "Generating Heapdump to '%s' now...\n", filename);
|
54
|
-
FILE* fp = fopen(filename, "w");
|
55
|
-
if (fp == NULL) abort();
|
56
|
-
|
57
|
-
// Create heapdump, depending on which Node.js version this can differ
|
58
|
-
// for now, just support Node.js 7 and higher
|
59
|
-
const HeapSnapshot* snap = v8::Isolate::GetCurrent()->GetHeapProfiler()->TakeHeapSnapshot();
|
60
|
-
|
61
|
-
FileOutputStream stream(fp);
|
62
|
-
snap->Serialize(&stream, HeapSnapshot::kJSON);
|
63
|
-
fclose(fp);
|
64
|
-
|
65
|
-
fprintf(stderr, "Done! Exiting process now.\n");
|
66
|
-
exit(1);
|
67
|
-
}
|
68
|
-
|
69
|
-
void ParseArgumentsAndSetErrorHandler(const FunctionCallbackInfo<Value>& args) {
|
70
|
-
Isolate* isolate = args.GetIsolate();
|
71
|
-
isolate->SetOOMErrorHandler(OnOOMError);
|
72
|
-
|
73
|
-
// parse JS arguments
|
74
|
-
// 1: filename
|
75
|
-
// 2: addTimestamp boolean
|
76
|
-
#if NODE_VERSION_AT_LEAST(13, 0, 0)
|
77
|
-
Local<Context> context = isolate->GetCurrentContext();
|
78
|
-
String::Utf8Value fArg(isolate, args[0]->ToString(context).ToLocalChecked());
|
79
|
-
#elif NODE_VERSION_AT_LEAST(12, 0, 0)
|
80
|
-
String::Utf8Value fArg(isolate, args[0]->ToString(isolate));
|
81
|
-
#elif NODE_VERSION_AT_LEAST(9, 0, 0)
|
82
|
-
String::Utf8Value fArg(isolate, args[0]->ToString());
|
83
|
-
#else
|
84
|
-
String::Utf8Value fArg(args[0]->ToString());
|
85
|
-
#endif
|
86
|
-
strncpy(filename, (const char*)(*fArg), sizeof(filename) - 1);
|
87
|
-
|
88
|
-
#if NODE_VERSION_AT_LEAST(12, 0, 0)
|
89
|
-
addTimestamp = args[1]->BooleanValue(isolate);
|
90
|
-
#else
|
91
|
-
addTimestamp = args[1]->BooleanValue();
|
92
|
-
#endif
|
93
|
-
}
|
94
|
-
|
95
|
-
void init(Local<Object> exports) {
|
96
|
-
NODE_SET_METHOD(exports, "call", ParseArgumentsAndSetErrorHandler);
|
97
|
-
}
|
98
|
-
|
99
|
-
NODE_MODULE(NODE_OOM_HEAPDUMP_NATIVE, init)
|
package/tests/index.js
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
let cp = require("child_process");
|
2
|
-
let fs = require("fs");
|
3
|
-
let path = require("path");
|
4
|
-
|
5
|
-
describe('Heapdumps', function () {
|
6
|
-
it('should be created in x seconds', function (done) {
|
7
|
-
this.timeout(250000);
|
8
|
-
|
9
|
-
let child = cp.fork(path.resolve(__dirname, './oom_app.js'), null, {
|
10
|
-
cmd: path.dirname(require.main.filename),
|
11
|
-
stdio: 'inherit',
|
12
|
-
execArgv: ["--max_old_space_size=40", "--optimize_for_size", "--always_compact", "--inspect=9229"]
|
13
|
-
});
|
14
|
-
|
15
|
-
setTimeout(function () {
|
16
|
-
child.kill();
|
17
|
-
fs.lstat(path.resolve(__dirname, "../abc.heapsnapshot"), (err, stats) => {
|
18
|
-
if (!err && stats.isFile()) {
|
19
|
-
done();
|
20
|
-
} else {
|
21
|
-
done(err);
|
22
|
-
}
|
23
|
-
clearTimeout(handle);
|
24
|
-
})
|
25
|
-
}, 20000);
|
26
|
-
});
|
27
|
-
});
|
@@ -1,27 +0,0 @@
|
|
1
|
-
let oomLib = require("../index.js")({
|
2
|
-
heapdumpOnOOM: false
|
3
|
-
});
|
4
|
-
|
5
|
-
var i = 0;
|
6
|
-
var path = "";
|
7
|
-
|
8
|
-
var handle = setInterval(function () {
|
9
|
-
i++;
|
10
|
-
|
11
|
-
oomLib.createHeapSnapshot(require("path").resolve("../", "myName")).then((p) => {
|
12
|
-
path = p;
|
13
|
-
}).catch((err) => {
|
14
|
-
console.error(err);
|
15
|
-
});
|
16
|
-
|
17
|
-
if (i === 3) {
|
18
|
-
oomLib.deleteHeapSnapshot(path).then(() => {
|
19
|
-
//
|
20
|
-
}).catch((err) => {
|
21
|
-
console.error("err", err);
|
22
|
-
});
|
23
|
-
setTimeout(function () {
|
24
|
-
process.exit(0);
|
25
|
-
}, 100);
|
26
|
-
}
|
27
|
-
}, 2000);
|
@@ -1,35 +0,0 @@
|
|
1
|
-
let oomLib = require("../index.js")({
|
2
|
-
heapdumpOnOOM: false
|
3
|
-
});
|
4
|
-
|
5
|
-
var i = 0;
|
6
|
-
var path = "";
|
7
|
-
|
8
|
-
oomLib.createCpuProfile(require("path").resolve("myCPU.cpuprofile"), 3000).then((p) => {
|
9
|
-
console.error("CPU profile", p);
|
10
|
-
|
11
|
-
//oomLib.deleteAllCpuProfiles();
|
12
|
-
}).catch((err) => {
|
13
|
-
console.error(err);
|
14
|
-
});
|
15
|
-
|
16
|
-
var handle = setInterval(function () {
|
17
|
-
i++;
|
18
|
-
|
19
|
-
oomLib.createHeapSnapshot(require("path").resolve("../", "myName")).then((p) => {
|
20
|
-
path = p;
|
21
|
-
}).catch((err) => {
|
22
|
-
console.error(err);
|
23
|
-
});
|
24
|
-
|
25
|
-
if (i === 5) {
|
26
|
-
/* oomLib.deleteHeapSnapshot(path).then(() => {
|
27
|
-
//
|
28
|
-
}).catch((err) => {
|
29
|
-
console.error("err", err);
|
30
|
-
});*/
|
31
|
-
setTimeout(function () {
|
32
|
-
process.exit(0);
|
33
|
-
}, 100);
|
34
|
-
}
|
35
|
-
}, 1000);
|
package/tests/oom_app.js
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
let path = require('path');
|
2
|
-
|
3
|
-
let oom = require("../index.js")({
|
4
|
-
path: path.resolve(__dirname, 'my_heapdump'),
|
5
|
-
heapdumpOnOOM: true,
|
6
|
-
//OOMImplementation: "GC_MONITORING", // use the old implementation
|
7
|
-
addTimestamp: false
|
8
|
-
});
|
9
|
-
|
10
|
-
// It is important to use named constructors (like the one below), otherwise
|
11
|
-
// the heap snapshots will not produce useful outputs for you.
|
12
|
-
function LeakingClass1() {
|
13
|
-
}
|
14
|
-
|
15
|
-
var leaks = [];
|
16
|
-
var handle = setInterval(function () {
|
17
|
-
for (var i = 0; i < 100000; i++) {
|
18
|
-
leaks.push(new LeakingClass1);
|
19
|
-
}
|
20
|
-
|
21
|
-
console.error('Leaks: %d', leaks.length);
|
22
|
-
}, 100);
|