Repository navigation
NODE_V8_COVERAGE can run OOM when compiling a lot of scripts in one process #44364
Description
Activity
- addedcoverageIssues and PRs related to Node.js code coverage support.Issues and PRs related to Node.js code coverage support.
on Aug 23, 2022 Another idea: instead of periodically collecting the coverage, we collect the coverage when the heap size limit is about to be reached, it's probably easier to implement(?), and would result in fewer coverage files.
Reacted by liuxingbaoyu and Benjamin E. Coe@joyeecheung I seem to recall that "best effort" coverage may break some of the report tooling, leading to confusing results . If we could figure out how to dump coverage periodically that sounds ideal.
I looked into this a bit, and looks like simply collecting the coverage with the current configuration wouldn't result in cleanups of the feedback vectors, because V8 only cleans them up when collecting binary coverage (i.e. when
callCountofProfiler.startPreciseCoverageis set to false so that V8 only records if a function is invoked, but not the precise invocation counts). So I have a few questions @bcoe:- How useful is it in practice to have the actual invocation count? One way to go about it would be to add a configuration option to tell NODE_V8_COVERAGE to collect binary coverage instead, so that the feedback can be freed up after coverage collection.
- Or, we might be able to just add an option to V8 to clean the feedback up even when it's collecting invocation counts if the counts can be merged by the consumer in the end (from what I can tell that's what c8 and probably other v8 coverage tools do).
Reacted by Chengzhong WuHow useful is it in practice to have the actual invocation count? One way to go about it would be to add a configuration option to tell NODE_V8_COVERAGE to collect binary coverage instead, so that the feedback can be freed up after coverage collection.
There is value in invocation counts, as it can help in determining hot spots in your application that are worth optimizing.
However, I think for many use cases having a binary value of whether or not a line was hit would be sufficient.
Or, we might be able to just add an option to V8 to clean the feedback up even when it's collecting invocation counts if the counts can be merged by the consumer in the end (from what I can tell that's what c8 and probably other v8 coverage tools do).
This sounds quite reasonable, this is exactly what c8 does.
github-actions commented
on Jun 25, 2026 on Jun 25, 2026 – with GitHub ActionsContributorMore actionsThis issue has been marked as stale due to 210 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Jun 25, 2026 bump
- removedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Jun 26, 2026 github-actions commented
on Sep 25, 2026 on Sep 25, 2026 – with GitHub ActionsContributorMore actionsThis issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Sep 25, 2026 bump
- removedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Sep 26, 2026
For more context, see https://bugs.chromium.org/p/v8/issues/detail?id=13183. In summary, in Node.js NODE_V8_COVERAGE is implemented by taking precise coverage, which holds on to all the feedback vectors of every function (including scripts) that has ever been compiled, even after the functions are gone. My understanding that this is by-design for precise coverage - by the time the coverage is collected, it's possible that the functions have already been GC'ed, but V8 still needs to consult the feedback vectors for invocation counts that were recorded when the functions were still alive. As an alternative V8 provides best-effort coverage that does not hold on to feedback vectors but as a result the data from functions that have been GC'ed by the time the coverage is taken can be missing.
Reproduction (h/t @ptomato):
I think there are two options to tackle this:
Infinityto tell Node.js to go back to the current behavior.cc @bcoe