-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: use inspector for heap profiles #236
base: main
Are you sure you want to change the base?
Conversation
🤖 I detect that the PR title and the commit message differ and there's only one commit. To use the PR title for the commit history, you can use Github's automerge feature with squashing, or use -- conventional-commit-lint bot |
75d2335
to
23eab92
Compare
|
||
export function startSamplingHeapProfiler( | ||
heapIntervalBytes: number, | ||
stackDepth: number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove "stack depth", since it's no longer in use.
{heapIntervalBytes}, | ||
(err: Error | null): void => { | ||
if (err !== null) { | ||
console.error(`Error starting heap sampling: ${err}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing should be logged within this repo (cloud-profiler-nodejs will log errors occurring; logging anything directly here will either result in things being double logged, or prevent users from being able to control what is logged)
@@ -84,17 +83,17 @@ export function profile( | |||
* started with different parameters, this throws an error. | |||
* | |||
* @param intervalBytes - average number of bytes between samples. | |||
* @param stackDepth - maximum stack depth for samples collected. | |||
* @param stackDepth - maximum stack depth for samples collected. This is currently no-op. | |||
* Default stack depth of 128 will be used. Kept to avoid making breaking change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd favor making the breaking change here (over keeping behavior which no longer works).
Kokoro system tests have failed with the following (suggesting that maybe the heap profile isn't being written out successfully any more):
|
|
||
/** | ||
* Need to create this interface since the type definitions file for node inspector | ||
* at https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/inspector.d.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might open an issue in that repo and link it here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, will do that.
result.profile as CompatibleSamplingHeapProfile; | ||
resolve( | ||
translateToAllocationProfileNode( | ||
compatibleHeapProfile.head, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit since these are the only two fields in compatibleHeapProfile, just pass it directly here
children: [], | ||
}; | ||
|
||
const children: AllocationProfileNode[] = new Array<AllocationProfileNode>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node.children.map()
should give the same result without all the boilerplate?
nodeId: number, | ||
samples: SamplingHeapProfileSample[] | ||
): SamplingHeapProfileSample[] { | ||
const filtered = samples.filter((sample: SamplingHeapProfileSample) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd create a map in the outer scope or closure of the recursive function to do this lookup in constant time as this is n^2 now. Check out my PR for cpu time if you don't what i mean
return filtered; | ||
} | ||
|
||
function createAllocationsFromSamplesForNode( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldnt this be done once in linear time for all nodes, since the samples already have node ID? Group by node ID then for each group, group by byte sizes being equal?
); | ||
} | ||
heapIntervalBytes = intervalBytes; | ||
heapStackDepth = stackDepth; | ||
startSamplingHeapProfiler(heapIntervalBytes, heapStackDepth); | ||
startSamplingHeapProfiler(heapIntervalBytes, stackDepth); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function will return before the promise completes as it's fire and forget with this promise, might be why the test is failing
For heap profiling, replaces the native C++ addon with calls to Node's inspector module. This uses the same V8::CpuProfiler under the hood but communicates over the chrome devtools protocol.
A similar PR has been raised to determine viability of using Node's inspector module for time profiling.
Testing
Caveats
stackDepth
parameter to the heap profile is still preserved here to avoid breaking changes, this parameter is a no-op now. Stack depth will default to 128. This is based on the native source code of the V8 heap profiler.Flame graph generated using the in-built inspector
Flame graph generated using the C++ addon
The graphs look similar, but there are differences, mostly due to the
serializeHeapProfile
task. When using the in-built inspector, this process takes about 1.55MB, while in the implementation that used C++ addon, this process took 0.81MB.This accounts for most difference b/w the memory usage reported by the different profilers.