@@ -34,6 +34,7 @@ import {isMainThread} from 'worker_threads';
3434
3535let enabled = false ;
3636let heapIntervalBytes = 0 ;
37+ let heapStackDepth = 0 ;
3738let 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
97108export 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