Skip to content

Change heap dumps to use HEAP2 as the default - #127321

Merged
hoyosjs merged 6 commits into
dotnet:mainfrom
hoyosjs:juhoyosa/heap2-default
Apr 24, 2026
Merged

Change heap dumps to use HEAP2 as the default#127321
hoyosjs merged 6 commits into
dotnet:mainfrom
hoyosjs:juhoyosa/heap2-default

Conversation

@hoyosjs

Copy link
Copy Markdown
Member

This pull request simplifies and unifies the logic for memory region enumeration when generating heap dumps. It makes HEAP2 the default heap dump and deprecates old env vars that work around slow dumps. It assumes LocaderAllocators have all necessary data. This path does a few things better and is higher perf. It enumerates the following:

Enumerates
JitManager -> Code Heaps
SystemDomain -> GlobalLoaderAllocator (was missing before partially).
AppDomain -> LoaderAllocator
Assembly -> LoaderAllocator
Module -> LoaderAllocator
LoaderAllocator -> All Loader Heaps (also collecting collectible ones now).

It skips

  • Objects living in the loader alloc: Module hashtables, ClassLoader explicit enumeration, EEClass MethodDescChunks, MethodTable DispatchMap.
  • Thread AppDomain, Debugger Module info, Debugger MethodDesc info which have already been enumerated.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR changes CoreCLR heap-dump memory region enumeration to use the HEAP2 path by default, removing legacy/slow enumeration paths and createdump environment-variable workarounds.

Changes:

  • Removes several legacy EnumMemoryRegions sub-enumerations that were skipped for HEAP2 and primarily supported the older heap-dump path.
  • Forces heap dump generation through CLRDATA_ENUM_MEM_HEAP2 in DAC enumeration and createdump’s DAC-based region enumeration.
  • Simplifies the “custom dump” enumeration worker to a single mini-style path.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/vm/threads.cppRemoves AppDomain enumeration from thread region enumeration for non-HEAP2 legacy paths.
src/coreclr/vm/methodtable.cppDrops DispatchMap explicit enumeration for legacy non-HEAP2 dump paths.
src/coreclr/vm/class.cppRemoves explicit Module + MethodDescChunk enumeration for legacy non-HEAP2 dump paths.
src/coreclr/vm/ceeload.cppRemoves extensive Module hashtable/type/member explicit enumeration for legacy non-HEAP2 dump paths; keeps HEAP2 loader allocator enumeration.
src/coreclr/vm/assembly.cppRemoves legacy Assembly sub-enumerations; keeps HEAP2 loader allocator enumeration only.
src/coreclr/debug/ee/functioninfo.cppRemoves legacy debugger module/methoddesc/sequence-map explicit enumeration for non-HEAP2 paths.
src/coreclr/debug/daccess/enummem.cppMakes heap dumps always run via HEAP2; simplifies Custom dump worker and removes HEAP handling in wrapper.
src/coreclr/debug/createdump/crashinfo.cppRemoves env-var-based opt-out/compat behavior; always uses HEAP2 for DAC-based enumeration.

Comment threadsrc/coreclr/debug/daccess/enummem.cpp
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Comment threadsrc/coreclr/debug/createdump/crashinfo.cpp Outdated
Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI review requested due to automatic review settings April 23, 2026 17:15

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/debug/daccess/enummem.cpp
Comment threadsrc/coreclr/debug/createdump/crashinfo.cpp
Comment threadsrc/coreclr/debug/createdump/crashinfo.cpp Outdated
Comment threadsrc/coreclr/debug/createdump/crashinfo.cpp Outdated
Comment threadsrc/coreclr/debug/createdump/crashinfo.cpp Outdated
Comment threadsrc/coreclr/debug/createdump/crashinfo.cpp Outdated
Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com>
CopilotAI review requested due to automatic review settings April 23, 2026 21:45

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/coreclr/debug/daccess/enummem.cpp:1951

  • EnumMemoryRegionsWrapper() no longer handles CLRDATA_ENUM_MEM_HEAP even though it remains a public flag in clrdata.h. Passing CLRDATA_ENUM_MEM_HEAP will now hit the debug assert and (in retail) effectively do nothing while still returning S_OK. Consider mapping HEAP -> HEAP2 for backward compatibility, or returning a failing HRESULT (e.g., E_INVALIDARG) to avoid silent success.
 else if (flags == CLRDATA_ENUM_MEM_TRIAGE)
{
// triage micro-dump
status = EnumMemoryRegionsWorkerMicroTriage(flags);
}
else if (flags == CLRDATA_ENUM_MEM_HEAP2)
{
status = EnumMemoryRegionsWorkerHeap(flags);
}
else
{
_ASSERTE(!"Bad flags passing to EnumMemoryRegionsWrapper!");
}
}

Comment threadsrc/coreclr/debug/daccess/enummem.cpp
@hoyosjs
hoyosjs enabled auto-merge (squash) April 23, 2026 22:56
@hoyosjs
hoyosjs merged commit c835d0f into dotnet:mainApr 24, 2026
109 checks passed
@hoyosjs
hoyosjs deleted the juhoyosa/heap2-default branch April 24, 2026 08:09
@rcj1rcj1 mentioned this pull request Apr 28, 2026
hoyosjs added a commit that referenced this pull request May 13, 2026
Fixes#122459
main PRs:
- #125631
- #125459
- #127321
# Description
Backports three DAC performance improvements for minidump collection:
1. **Use SHash as DAC instance hash (#125631):** Replaces the
hand-rolled hash table in `DacInstanceManager` with an `SHash`-based
implementation. The previous fixed-bucket hash degraded quickly for Find
and insertion operations under high load. Measured ~9.5x speedup for
minidump collection against a repro app with 2.5k-frame deep stacks over
50 threads.
2. **Cache debugger patches (#125459):** Caches the list of debugger
breakpoint patches so that x64 stack unwinding doesn't re-scan the
1,000-bucket patch hash table on every frame. The cache is populated
once on first access and invalidated on `Flush()`. Measured reduction
from 55s to ~7s for minidump collection (10,000 iterations across 10
threads).
3. **Enable CLRDATA_ENUM_MEM_HEAP2 via environment variable:** When the
target process has `DOTNET_EnableFastHeapDumps` set, the DAC promotes
`CLRDATA_ENUM_MEM_HEAP` to `CLRDATA_ENUM_MEM_HEAP2`, which dumps loader
heap pages in bulk instead of walking individual runtime structures.
# Customer Impact
Customers collecting minidumps of large .NET applications (many threads,
deep stacks) experience extremely slow dump collection times - on the
order of minutes for what should take seconds. This directly impacts
incident response time in production environments. Without these fixes,
dump collection through Watson/dotnet-dump/createdump remains
unacceptably slow for large workloads.
# Regression
Yes, with respect to framework. Customers doing migrations have noticed
them - framework used non-portable variants of the MSVC library.
# Testing
- Both PRs (#125631, #125459) were merged to main and have been stable.
- Performance was measured against a repro app exercising deep stacks
across many threads, confirming the expected speedups.
- The env var change is gated behind an explicit opt-in
(`DOTNET_EnableFastHeapDumps`), so no change in default behavior. This
is the riskier change since it makes heap dump match our expectations
but might yield unknown!unknown if the modules aren't indexed properly.
# Risk
**Low.** - The SHash and patch cache changes are confined to DAC-only code paths
(`daccess.cpp`, `dacfn.cpp`, `dacimpl.h`) that execute only during
diagnostic operations (dump collection, debugging). They do not affect
runtime execution.
- The `DOTNET_EnableFastHeapDumps` env var is opt-in and does not change
default behavior.
- All three changes have been running in main since March without
reported issues.
hoyosjs added a commit that referenced this pull request May 13, 2026
Fixes#122459
main PRs:
- #125631
- #125459
- #127321
# Description
Backports three DAC performance improvements for minidump collection:
1. **Use SHash as DAC instance hash (#125631):** Replaces the
hand-rolled hash table in `DacInstanceManager` with an `SHash`-based
implementation. The previous fixed-bucket hash degraded quickly for Find
and insertion operations under high load. Measured ~9.5x speedup for
minidump collection against a repro app with 2.5k-frame deep stacks over
50 threads.
2. **Cache debugger patches (#125459):** Caches the list of debugger
breakpoint patches so that x64 stack unwinding doesn't re-scan the
1,000-bucket patch hash table on every frame. The cache is populated
once on first access and invalidated on `Flush()`. Measured reduction
from 55s to ~7s for minidump collection (10,000 iterations across 10
threads).
3. **Enable CLRDATA_ENUM_MEM_HEAP2 via environment variable:** When the
target process has `DOTNET_EnableFastHeapDumps` set, the DAC promotes
`CLRDATA_ENUM_MEM_HEAP` to `CLRDATA_ENUM_MEM_HEAP2`, which dumps loader
heap pages in bulk instead of walking individual runtime structures.
# Customer Impact
Customers collecting minidumps of large .NET applications (many threads,
deep stacks) experience extremely slow dump collection times - on the
order of minutes for what should take seconds. This directly impacts
incident response time in production environments. Without these fixes,
dump collection through Watson/dotnet-dump/createdump remains
unacceptably slow for large workloads.
# Regression
Yes, with respect to framework. Customers doing migrations have noticed
them - framework used non-portable variants of the MSVC library.
# Testing
- Both PRs (#125631, #125459) were merged to main and have been stable.
- Performance was measured against a repro app exercising deep stacks
across many threads, confirming the expected speedups.
- The env var change is gated behind an explicit opt-in
(`DOTNET_EnableFastHeapDumps`), so no change in default behavior. This
is the riskier change since it makes heap dump match our expectations
but might yield unknown!unknown if the modules aren't indexed properly.
# Risk
**Low.** - The SHash and patch cache changes are confined to DAC-only code paths
(`daccess.cpp`, `dacfn.cpp`, `dacimpl.h`) that execute only during
diagnostic operations (dump collection, debugging). They do not affect
runtime execution.
- The `DOTNET_EnableFastHeapDumps` env var is opt-in and does not change
default behavior.
- All three changes have been running in main since March without
reported issues.
@github-actionsgithub-actionsBot locked and limited conversation to collaborators May 24, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@hoyosjs@am11@rcj1@jkotas