[英]How to dump Java objects came from JVM heap old generation?
是否有任何工具可以轉儲舊一代的JVM堆?
換句話說,我如何判斷一個物體是來自年輕一代還是老一代?
如果運行Oracle JDK或OpenJDK,則可以使用HotSpot Serviceability Agent sa-jdi.jar
執行此sa-jdi.jar
。 它可以發現老一代的界限。 這是一個在OldGen邊界內的對象之間收集堆直方圖的示例。
也可以從Java進程中找到舊代的地址,參見相關問題 。
import sun.jvm.hotspot.gc_implementation.parallelScavenge.ParallelScavengeHeap;
import sun.jvm.hotspot.gc_interface.CollectedHeap;
import sun.jvm.hotspot.memory.GenCollectedHeap;
import sun.jvm.hotspot.memory.MemRegion;
import sun.jvm.hotspot.oops.ObjectHistogram;
import sun.jvm.hotspot.oops.Oop;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;
public class OldGen extends Tool {
public static void main(String[] args) {
new OldGen().execute(args);
}
@Override
public void run() {
MemRegion oldRegion = getOldRegion(VM.getVM().getUniverse().heap());
ObjectHistogram histogram = new ObjectHistogram() {
@Override
public boolean doObj(Oop obj) {
return oldRegion.contains(obj.getHandle()) && super.doObj(obj);
}
};
VM.getVM().getObjectHeap().iterate(histogram);
histogram.print();
}
private MemRegion getOldRegion(CollectedHeap heap) {
if (heap instanceof ParallelScavengeHeap) {
return ((ParallelScavengeHeap) heap).oldGen().objectSpace().usedRegion();
} else if (heap instanceof GenCollectedHeap) {
return ((GenCollectedHeap) heap).getGen(1).usedRegion();
} else {
throw new UnsupportedOperationException(heap.kind() + " is not supported");
}
}
}
一般來說,答案是否定的,沒有。 這是因為雖然JVM將堆組織到不同的部分,但是沒有一種僅查看舊區域的轉儲機制。 事實上,在較新的JVM上有幾種不同類型的區域,包括伊甸園,幸存者(一個和兩個)和老一代,其中可以包括新生成的幽默物體。
您可以使用jmap
或jcmd
執行堆轉儲,這些選項可以生成實時對象或所有內容。 如果你真的需要知道你可能能夠分析堆轉儲並確定它來自哪個區域,但總的來說,你真的不需要知道。 如果選擇“實時”對象,則它(實際上)將在heapdump上執行GC以刪除任何不被視為活動的對象。
一個更好的問題是嘗試理解你想要實現的目標,並確定是否有工具(如各種PrintGC *標志)可以顯示答案,例如對象的提升頻率。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.