Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java G1 GC: Programmatically finding the number of humongous regions before/after GC

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?

like image 815
haroba Avatar asked Mar 03 '23 04:03

haroba


1 Answers

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)

like image 145
apangin Avatar answered May 07 '23 07:05

apangin