Java G1 GC:以编程方式查找GC之前/之后的巨大区域的数量

har*_*oba 4 java garbage-collection jvm g1gc

我想以编程方式找到GC运行之前/之后的巨大区域数,以便将其报告给外部监视服务。

在使用ManagementFactory.getGarbageCollectorMXBeansand 之前/之后,我能够找到诸如GC操作,持续时间和内存使用情况之类的信息GarbageCollectionNotificationInfo,但是据我所知,没有明显的方法可以用相同的方式找到巨大区域的数量。

有什么方法可以以编程方式访问有关巨大区域的信息?

apa*_*gin 7

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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)