我想以编程方式找到GC运行之前/之后的巨大区域的数量,以便将其报告给外部监视服务。
我能够找到使用ManagementFactory.getGarbageCollectorMXBeans
和GarbageCollectionNotificationInfo
之前/之后的GC操作,持续时间和内存使用情况之类的信息,但据我所知,没有明显的方法可以找到该区域中巨大区域的数量。同样的方式。
有没有办法以编程方式访问有关巨大区域的信息?
JDK不会通过公共API导出此指标。但是,可以使用Unsafe技巧从JVM的内存中直接获取此信息。
HotSpot JVM出于调试目的发布其内部结构的偏移量。此信息称为VMStructs,可通过HotSpot Serviceability Agent获得。
这里是获取巨大区域数量的工具的外观。
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);
}
}
注意:此工具从外部Java进程获取信息。
我还有一个概念验证项目helfy,可以直接在JVM内部访问VMStructs。下面是一个示例,该示例如何计算正在运行的Java进程中的巨大区域:HumongousRegionSet.java
(该演示当前在Linux和Windows上运行;尚不支持macOS)