Skip to content

Commit c82c2e7

Browse files
committed
fix(allocations): stop the heap sampling when getting profile (#357)
1 parent 678b58d commit c82c2e7

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

ts/src/heap-profiler.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {isMainThread} from 'worker_threads';
3434

3535
let enabled = false;
3636
let heapIntervalBytes = 0;
37+
let heapStackDepth = 0;
3738
let startedWithAllocations = false;
3839

3940
/*
@@ -86,12 +87,22 @@ export function profile(
8687
sourceMapper?: SourceMapper,
8788
generateLabels?: GenerateAllocationLabelsFunction,
8889
): Profile {
89-
return convertProfile(
90+
const result = convertProfile(
9091
v8Profile(),
9192
ignoreSamplePath,
9293
sourceMapper,
9394
generateLabels,
9495
);
96+
// In allocation mode V8 keeps every sampled object (live + collected-by-GC)
97+
// in an append-only buffer that's only freed by stopSamplingHeapProfiler.
98+
// Without this reset, each call to getAllocationProfile re-reads the entire
99+
// history, so alloc_* totals grow linearly with wall-clock time and V8's
100+
// internal sample buffer leaks for the lifetime of the process.
101+
if (startedWithAllocations) {
102+
stopSamplingHeapProfiler();
103+
startSamplingHeapProfiler(heapIntervalBytes, heapStackDepth, true);
104+
}
105+
return result;
95106
}
96107

97108
export function convertProfile(
@@ -193,6 +204,7 @@ export function start(
193204
);
194205
}
195206
heapIntervalBytes = intervalBytes;
207+
heapStackDepth = stackDepth;
196208
startedWithAllocations = allocations;
197209
startSamplingHeapProfiler(intervalBytes, stackDepth, allocations);
198210
enabled = true;

0 commit comments

Comments
 (0)