I would like to programmatically find the number of humongous regions before/after a GC has run, in order to report it to an external monitoring service.
I'm able to find information like GC action, duration and memory usage before/after using ManagementFactory.getGarbageCollectorMXBeans
and GarbageCollectionNotificationInfo
, but as far as I can tell there is no obvious way to find the number of humongous regions in the same way.
Is there any way to programmatically access information about the number of humongous regions?
JDK does not export this metrics through the public API. However, it is possible to obtain this information right from the memory of the JVM using Unsafe tricks.
HotSpot JVM publishes the offsets of its internal structures for debugging purposes. This information is called VMStructs and is available through the HotSpot Serviceability Agent.
Here is how the tool to obtain the number of humongous regions will look like.
import sun.jvm.hotspot.gc_implementation.g1.G1CollectedHeap;
import sun.jvm.hotspot.gc_implementation.g1.HeapRegionSetCount;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;
public class HumongousRegionSet extends Tool {
@Override
public void run() {
G1CollectedHeap heap = (G1CollectedHeap) VM.getVM().getUniverse().heap();
HeapRegionSetCount count = heap.humongousSet().count();
System.out.printf("%d humongous regions of total capacity %d MB\n",
count.length(), count.capacity() >>> 20);
}
public static void main(String[] args) {
new HumongousRegionSet().execute(args);
}
}
Note: this tool gets the information from the external Java process.
I also have a proof-of-concept project helfy to access VMStructs right inside the JVM. Here is an example how to count humongous regions within the running Java process: HumongousRegionSet.java
(this demo currently works on Linux and Windows; no macOS support yet)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With