JVM扫盲(七)

From: 怎么找到什么东东被移到了老年代java

我怎么找到都是什么东东在转移到老年代????!oracle

一个笨方法就是使用这个option 启动java 应用: -XX:+TraceScavenge. 可是这个命令选项并无在正式JVM版本里发布, 须要找到一个debug版本的HotSpot JVM才能使用这个命令选项。 用了这个命令以后, 日志输出很冗长, 由于它会每次每一个在年轻代被处理的对象。工具

还有一个可能的办法就是从heap dumps中提取信息。 年轻代与用选项-XX:+PrintHeapAtGC获得的对便捷信息配合使用获得的heap dumps 能够帮助咱们找到堆积在老年代的对象们。spa

用一个简单的栗子演示下怎么作,先用命令行启动java 应用: 命令行

java -Xmx100m -XX:NewSize=10m -XX:+PrintGCDetails -XX:+HeapDumpBeforeFullGC -XX:+PrintHeapAtGC TestAppdebug

在4次年轻代回收以后, 老年代被填满而且致使Full GC。这时JVM会生成Heap Dump。OK, 那就分析下这个自动生成的Heap Dump找出都是什么东东转移到老年代。日志

GC 日志里显示了在GC#4(第四次GC)先后堆内存使用状况:对象

`{Heap before GC invocations=4 (full 0):
 PSYoungGen      total 17408K, used 17392K [0x00000000fdf00000, 0x0000000100000000, 0x0000000100000000)
  eden space 16384K, 100% used [0x00000000fdf00000,0x00000000fef00000,0x00000000fef00000)
  from space 1024K, 98% used [0x00000000fef00000,0x00000000feffc010,0x00000000ff000000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 68608K, used 34096K [0x00000000f9c00000, 0x00000000fdf00000, 0x00000000fdf00000)
  object space 68608K, 49% used [0x00000000f9c00000,0x00000000fbd4c000,0x00000000fdf00000)
 Metaspace       used 2612K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 285K, capacity 386K, committed 512K, reserved 1048576Kblog

[GC (Allocation Failure) [PSYoungGen: 17392K->1024K(32768K)] 51488K->52816K(101376K), 0.0101398 secs] [Times: user=0.00 sys=0.00, real=0.00内存

Heap after GC invocations=4 (full 0):
 PSYoungGen      total 32768K, used 1024K [0x00000000fdf00000, 0x0000000100000000, 0x0000000100000000)
  eden space 31744K, 0% used [0x00000000fdf00000,0x00000000fdf00000,0x00000000ffe00000)
  from space 1024K, 100% used [0x00000000fff00000,0x0000000100000000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 68608K, used 51792K [0x00000000f9c00000, 0x00000000fdf00000, 0x00000000fdf00000)
  object space 68608K, 75% used [0x00000000f9c00000,0x00000000fce94050,0x00000000fdf00000)
 Metaspace       used 2612K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 285K, capacity 386K, committed 512K, reserved 1048576K
}

Heap Dump (before full gc): Dumping heap to java_pid31684.hprof ... ` 注意,ParOldGen中的object space的占用内存明显增多, 如今可使用MAT(memory analysis tool)打开java_pid31684.hprof。可是在使用MAT分析heap dump以前, 需配置'Keep unreachable objects'。Keep unreachable objects 啥意思??? -> 保持没有被引用的对象。这样作是为了确保已经不在被引用,可是仍然存在于堆中的对象可以显示在MAT中。如何设置 'Keep unreachable objects'? -> 工具栏中 Window->Preferences->Memory Analyzer 找到'keep unreachable objects'选中便可。

从上面的GC日志中, 能够看出老年代起始地址: 0x00000000f9c00000, 在GC#4以前,老年代的终止地址:0x00000000fbd4c000,在GC#4以后,老年代增长到的终止地址: 0x00000000fce94050。这意味着由于GC#4而转移的对象在老年代的地址范围为 [0x00000000fbd4c000 ~ 0x00000000fce94050], 可使用OQL(Object Query Language) 查询在这个地址范围内的对象:

SELECT * FROM INSTANCEOF java.lang.Object t WHERE (toHex(t.@objectAddress) >= "0xfbd4c000" AND toHex(t.@objectAddress) <= "0xfce94050")

相关文章
相关标签/搜索