eclipse-mat / mat

The Eclipse Memory Analyzer is a fast and feature-rich Java heap dump analyzer that helps you find memory leaks and reduce memory consumption.
https://eclipse.dev/mat/
Eclipse Public License 2.0
50 stars 10 forks source link

Feature request: Add tenured heap icon decorator #34

Open eclipsewebmaster opened 3 months ago

eclipsewebmaster commented 3 months ago

| --- | --- | | Bugzilla Link | 573175 | | Status | NEW | | Importance | P3 enhancement | | Reported | Apr 26, 2021 16:16 EDT | | Modified | Feb 01, 2023 04:29 EDT | | Reporter | Kevin Grigorenko |

Description

In the same way there is a garbage collection root icon decorator (https://help.eclipse.org/latest/topic/org.eclipse.mat.ui.help/mimes/i-hoisgcroot.png), it would be nice if there was a decorator signifying that an object is in a tenured heap region to help differentiate between potentially transient versus long-lived objects. This is probably best left off by default to avoid the performance and memory overhead and then a preference may be selected to enable the decorators which creates a separate BitField to hold the state per object.

I couldn't find any metadata in HPROF dumps signifying the region ranges but DTFJ dumps seem to show the ranges through getSections: https://www.eclipse.org/openj9/docs/api/jdk8/platform/dtfj/com/ibm/dtfj/java/JavaHeap.html#getSections--

eclipsewebmaster commented 3 months ago

By G Xu on Apr 26, 2021 20:54

very cool idea.

eclipsewebmaster commented 3 months ago

By Andrew Johnson on Apr 27, 2021 01:50

You might be able to get information from OpenJDK VMs using MBEANs. That would have to be captured at the same time as the HPROF dump, but perhaps the HPROF dump provider could do that.\ For example, via JConsole running getHeapInfo:

garbage-first heap total 57344K, used 34021K [0x0000000604800000, 0x0000000800000000)\ region size 4096K, 4 young (16384K), 1 survivors (4096K)\ Metaspace used 34680K, capacity 35264K, committed 35456K, reserved 1081344K\ class space used 3702K, capacity 3885K, committed 3968K, reserved 1048576K

vmInfo()\ \ Heap address: 0x0000000604800000, size: 8120 MB, Compressed Oops mode: Zero based, Oop shift amount: 3\ CDS disabled.\ Compressed class space mapped at: 0x0000000800000000-0x0000000840000000, size: 1073741824\ Narrow klass base: 0x0000000800000000, Narrow klass shift: 0, Narrow klass range: 0x40000000

GC Precious Log:\ CPUs: 12 total, 12 available\ Memory: 32469M\ Large Page Support: Disabled\ NUMA Support: Disabled\ Compressed Oops: Enabled (Zero based)\ Heap Region Size: 4M\ Heap Min Capacity: 8M\ Heap Initial Capacity: 8M\ Heap Max Capacity: 8120M\ Pre-touch: Disabled\ Parallel Workers: 10\ Concurrent Workers: 3\ Concurrent Refinement Workers: 10\ Periodic GC: Disabled

Heap:\ garbage-first heap total 57344K, used 36208K [0x0000000604800000, 0x0000000800000000)\ region size 4096K, 6 young (24576K), 1 survivors (4096K)\ Metaspace used 35220K, capacity 35815K, committed 35968K, reserved 1081344K\ class space used 3735K, capacity 3919K, committed 3968K, reserved 1048576K

Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, OA=open archive, CA=closed archive, TAMS=top-at-mark-start (previous, next)\ | 0|0x0000000604800000, 0x0000000604c00000, 0x0000000604c00000|100%| O| |TAMS 0x0000000604c00000, 0x0000000604800000| Untracked \ | 1|0x0000000604c00000, 0x0000000604d6be00, 0x0000000605000000| 35%| O| |TAMS 0x0000000604c00000, 0x0000000604c00000| Untracked \ | 2|0x0000000605000000, 0x0000000605400000, 0x0000000605400000|100%|HS| |TAMS 0x0000000605400000, 0x0000000605000000| Complete \ | 3|0x0000000605400000, 0x0000000605800000, 0x0000000605800000|100%|HS| |TAMS 0x0000000605800000, 0x0000000605400000| Complete \ | 4|0x0000000605800000, 0x0000000605800000, 0x0000000605c00000| 0%| F| |TAMS 0x0000000605800000, 0x0000000605800000| Untracked \ | 5|0x0000000605c00000, 0x0000000605c00000, 0x0000000606000000| 0%| F| |TAMS 0x0000000605c00000, 0x0000000605c00000| Untracked \ | 6|0x0000000606000000, 0x0000000606400000, 0x0000000606400000|100%| O| |TAMS 0x0000000606006a00, 0x0000000606000000| Untracked \ | 7|0x0000000606400000, 0x0000000606400000, 0x0000000606800000| 0%| F| |TAMS 0x0000000606400000, 0x0000000606400000| Untracked \ | 8|0x0000000606800000, 0x00000006069f0388, 0x0000000606c00000| 48%| S|CS|TAMS 0x0000000606800000, 0x0000000606800000| Complete \ | 9|0x0000000606c00000, 0x0000000606ecebc8, 0x0000000607000000| 70%| E| |TAMS 0x0000000606c00000, 0x0000000606c00000| Complete \ | 10|0x0000000607000000, 0x0000000607400000, 0x0000000607400000|100%| E|CS|TAMS 0x0000000607000000, 0x0000000607000000| Complete \ | 11|0x0000000607400000, 0x0000000607800000, 0x0000000607800000|100%| E|CS|TAMS 0x0000000607400000, 0x0000000607400000| Complete \ | 12|0x0000000607800000, 0x0000000607c00000, 0x0000000607c00000|100%| E|CS|TAMS 0x0000000607800000, 0x0000000607800000| Complete \ | 13|0x0000000607c00000, 0x0000000608000000, 0x0000000608000000|100%| E|CS|TAMS 0x0000000607c00000, 0x0000000607c00000| Complete

Card table byte_map: [0x00000281e6340000,0x00000281e7320000] _byte_map_base: 0x00000281e331c000

Marking Bits (Prev, Next): (CMBitMap) 0x00000281d054a280, (CMBitMap) 0x00000281d054a2c0\ Prev Bits: [0x00000281e8300000, 0x00000281f01e0000)\ Next Bits: [0x00000281f01e0000, 0x00000281f80c0000)

Polling page: 0x00000281d0330000

Metaspace:

Usage:\ Non-class: 31.15 MB capacity, 30.75 MB ( 99%) used, 344.77 KB ( 1%) free+waste, 65.81 KB ( <1%) overhead. \ Class: 3.83 MB capacity, 3.65 MB ( 95%) used, 159.11 KB ( 4%) free+waste, 24.69 KB ( <1%) overhead. \ Both: 34.98 MB capacity, 34.40 MB ( 98%) used, 503.88 KB ( 1%) free+waste, 90.50 KB ( <1%) overhead.

Virtual space:\ Non-class space: 32.00 MB reserved, 31.25 MB ( 98%) committed \ Class space: 1.00 GB reserved, 3.88 MB ( <1%) committed \ Both: 1.03 GB reserved, 35.12 MB ( 3%) committed

Chunk freelists:\ Non-Class: 40.00 KB\ Class: 17.00 KB\ Both: 57.00 KB

MaxMetaspaceSize: 17179869184.00 GB\ CompressedClassSpaceSize: 1.00 GB

CodeHeap 'non-profiled nmethods': size=120000Kb used=7262Kb max_used=7262Kb free=112737Kb\ bounds [0x00000281dd180000, 0x00000281dd8a0000, 0x00000281e46b0000]\ CodeHeap 'profiled nmethods': size=120000Kb used=11605Kb max_used=12126Kb free=108394Kb\ bounds [0x00000281d5c50000, 0x00000281d6840000, 0x00000281dd180000]\ CodeHeap 'non-nmethods': size=5760Kb used=1399Kb max_used=1499Kb free=4361Kb\ bounds [0x00000281d56b0000, 0x00000281d5920000, 0x00000281d5c50000]\ total_blobs=7243 nmethods=6528 adapters=625\ compilation: enabled\ stopped_count=0, restarted_count=0\ full_count=0

eclipsewebmaster commented 3 months ago

By Andrew Johnson on Apr 27, 2021 01:53

jcmd VM.info

gives similar information.

eclipsewebmaster commented 3 months ago

By Andrew Johnson on Apr 27, 2021 04:50

We might want to show more information than just tenured or not, and ideally queries could be written which use this information. E.g. links from objects in the old region to objects in the new region might be more interesting that other inter or intra-regional links.

We could add some APIs - but we would need to spend some time on getting a good, clean, but general API.

A work-around might be to define dummy objects for the regions, and then have a link from an object to a region (rather than vice versa, which would mess up liveness). That might be use memory to store the link. Perhaps if objects had a dummy field the heap object reader could fill that in.

Perhaps region information could be generalized for other off-heap memory such as direct byte buffers, or byte code or jitted code, or stack frames, or class metaspace or "perm gen", or DLL locations.

eclipsewebmaster commented 3 months ago

By Kevin Grigorenko on Apr 27, 2021 09:41

A work-around might be to define dummy objects for the regions, and then have a link from an object to a region (rather than vice versa, which would mess up liveness).

That's a nice way to avoid complicating the API.

Perhaps region information could be generalized for other off-heap memory such as direct byte buffers, or byte code or jitted code, or stack frames, or class metaspace or "perm gen", or DLL locations.

That's a great idea.