深入理解java虚拟机(七):java垃圾收集分析总结
来源:互联网 发布:qq聊天记录软件 编辑:程序博客网 时间:2024/05/20 16:10
深入理解java虚拟机(一):java内存区域(内存结构划分)
深入理解java虚拟机(二):java内存溢出实战
深入理解java虚拟机(三):String.intern()-字符串常量池
深入理解java虚拟机(四):对象存活判定算法和垃圾收集算法
深入理解java虚拟机(五):hotspot垃圾收集算法实现
深入理解java虚拟机(六):java垃圾收集分析实战(内存分配与回收策略)
深入理解java虚拟机(七):java垃圾收集分析总结
深入理解java虚拟机(八):java内存分析工具-MAT和OQL
一、垃圾回收触发条件
1、Minor gc触发条件
当新生代空间不足时会主动触发Minor gc,并且自动扩容(可通过控制使新生代直接处于最大内存空间,避免自动扩容和垃圾收集)。
2、Full gc触发条件
和新生代一样,当老年代空间不足时会触发Full gc,并且自动扩容;另外当在代码中调用System.gc()时也会触发Full gc。 可通过参数-XX:+DisableExplicitGC 控制使System.gc()失效。
3、永久待触发条件
类似上面,当永久待空间不足时,会发出Full gc,可通过控制PermSize=MaxPermSize 避免自动扩容和垃圾回收。另外可通过参数-Xnoclassgc 来控制虚拟机不对类(永久待类对象)进行回收。
二、Runtime.exec创建新进程(内存叠加)占用外部内存
java虚拟机执行Runtime.exec 的过程是:首先克隆一个和当前虚拟机拥有一样环境变量的进程,再用这个心的进程区执行外部命令,最后再退出这个进程。
如果频繁执行,系统的消耗会很大,不仅是cpu还有内存。
另外这个时候要注意了,在采集java程序的内存时,一定要注意有java程序通过Runtime.exec创建的新进程所占用的内存,按理来说,java创建的新进程所占用的内存也应该归属于这个java程序的内存。
例:下面是在redhat下面用java程序通过Runtime.exec执行shell脚本。
import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.util.Date;public class TestSleep { public static void main(String[] args) { System.out.println("being sleep"+new Date().toLocaleString()); try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("/home/boco/script/sleep.sh"); InputStream stdin = proc.getInputStream(); InputStreamReader isr = new InputStreamReader(stdin); BufferedReader br = new BufferedReader(isr); String line = null; System.out.println("output"); while ( (line = br.readLine()) != null) System.out.println(line); System.out.println(""); int exitVal = proc.waitFor(); System.out.println("Process exitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } System.out.println("end sleep"+new Date().toLocaleString()); }}
shell脚本内容:
#!/bin/bashecho "begin"sleep 10echo "end"
执行结果:
可以看出有java进程产生了一个子进程,即shell脚本,而这个shell脚本又产生了一个子进程,即sleep。
三、类加载-字节码验证时间
类加载时间即虚拟机加载类所耗掉的总时间。
字节码验证会耗掉一部分时间,在保证字节码是安全的情况下,可以通过参数 -Xverify:none禁止掉字节码验证过程。
四、编译时间
编译时间:指虚拟机的JIT编译器(Just in time Compiler)编译热点代码(Hot Spot Code)的耗时。
我们知道java语言为了实现跨平台的特性, java代码编译出来后形成的class文件中存储的是字节码(ByteCode),虚拟机通过解释方式执行字节码命令,比起c语言的编译执行速度要慢不少。 不过在java1.2后,虚拟机内置了2个运行期间编译器(代号为C1和C2,C1在client模式下启用,C2在server模式下启用),如果一个java方法被调用数次到一定程度就会被判定为热代码交个JIT编译器编译为本地代码, 提高运行速度,这就是hotspot虚拟机名字的由来。
编译时间总长即为编译热代码所消耗的时间总和。
五、垃圾收集打印参数
-XX:+PrintGCApplicationStoppedTime 参数打印gc停顿时间
-XX:+PrintGCDateStamps 参数打印gc时间戳,系统时间
-XX:+PrintGCTimeStamps 参数打印gc时间,相对于jvm启动时间
-Xloggc:gclog.log 设置gc日志文件
-XX:+PrintReferenceGC 打印gc引用
-XX:+PrintGCApplicationConcurrentTime 打印每次垃圾回收前,程序未中断的执行时间
-XX:+PrintHeapAtGC 打印GC前后的详细堆栈信息
例:
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -Xloggc:gclog.log -XX:+PrintGCApplicationConcurrentTime -XX:+PrintHeapAtGC
输出gclog.log:
Application time: 0.0055586 seconds{Heap before GC invocations=0 (full 0): def new generation total 9216K, used 6487K [0x32750000, 0x33150000, 0x33150000) eden space 8192K, 79% used [0x32750000, 0x32da5fd0, 0x32f50000) from space 1024K, 0% used [0x32f50000, 0x32f50000, 0x33050000) to space 1024K, 0% used [0x33050000, 0x33050000, 0x33150000) tenured generation total 10240K, used 0K [0x33150000, 0x33b50000, 0x33b50000) the space 10240K, 0% used [0x33150000, 0x33150000, 0x33150200, 0x33b50000) compacting perm gen total 12288K, used 377K [0x33b50000, 0x34750000, 0x37b50000) the space 12288K, 3% used [0x33b50000, 0x33bae748, 0x33bae800, 0x34750000) ro space 10240K, 55% used [0x37b50000, 0x380d1140, 0x380d1200, 0x38550000) rw space 12288K, 55% used [0x38550000, 0x38bf44c8, 0x38bf4600, 0x39150000)2014-02-26T15:44:05.625+0800: 0.049: [GC 0.049: [DefNew: 6487K->151K(9216K), 0.0040768 secs] 6487K->6295K(19456K), 0.0041381 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap after GC invocations=1 (full 0): def new generation total 9216K, used 151K [0x32750000, 0x33150000, 0x33150000) eden space 8192K, 0% used [0x32750000, 0x32750000, 0x32f50000) from space 1024K, 14% used [0x33050000, 0x33075ee8, 0x33150000) to space 1024K, 0% used [0x32f50000, 0x32f50000, 0x33050000) tenured generation total 10240K, used 6144K [0x33150000, 0x33b50000, 0x33b50000) the space 10240K, 60% used [0x33150000, 0x33750030, 0x33750200, 0x33b50000) compacting perm gen total 12288K, used 377K [0x33b50000, 0x34750000, 0x37b50000) the space 12288K, 3% used [0x33b50000, 0x33bae748, 0x33bae800, 0x34750000) ro space 10240K, 55% used [0x37b50000, 0x380d1140, 0x380d1200, 0x38550000) rw space 12288K, 55% used [0x38550000, 0x38bf44c8, 0x38bf4600, 0x39150000)}Total time for which application threads were stopped: 0.0043639 secondsHeap def new generation total 9216K, used 4575K [0x32750000, 0x33150000, 0x33150000) eden space 8192K, 54% used [0x32750000, 0x32ba1fa8, 0x32f50000) from space 1024K, 14% used [0x33050000, 0x33075ee8, 0x33150000) to space 1024K, 0% used [0x32f50000, 0x32f50000, 0x33050000) tenured generation total 10240K, used 6144K [0x33150000, 0x33b50000, 0x33b50000) the space 10240K, 60% used [0x33150000, 0x33750030, 0x33750200, 0x33b50000) compacting perm gen total 12288K, used 377K [0x33b50000, 0x34750000, 0x37b50000) the space 12288K, 3% used [0x33b50000, 0x33bae748, 0x33bae800, 0x34750000) ro space 10240K, 55% used [0x37b50000, 0x380d1140, 0x380d1200, 0x38550000) rw space 12288K, 55% used [0x38550000, 0x38bf44c8, 0x38bf4600, 0x39150000)Application time: 0.0007510 seconds
- 深入理解java虚拟机(七):java垃圾收集分析总结
- 深入理解java虚拟机(七):java垃圾收集分析总结
- Java垃圾收集算法—深入理解Java虚拟机(七)
- 深入理解Java虚拟机3~垃圾收集器参数总结
- 深入理解Java虚拟机:垃圾收集
- 深入理解java虚拟机(五)垃圾收集器
- 深入理解Java虚拟机(三)-垃圾收集
- 深入理解Java虚拟机(四)-垃圾收集算法
- 探索深入理解java虚拟机之垃圾收集(4)
- 垃圾收集器(摘抄的深入理解JAVA虚拟机)
- 深入理解Java虚拟机之垃圾收集算法(1)
- 深入理解Java虚拟机之垃圾收集算法(2)
- 深入理解Java虚拟机之垃圾收集算法(3)
- 深入理解Java虚拟机学习总结(二) 垃圾收集器与内存分配策略
- 深入理解java虚拟机【Java虚拟机垃圾收集器】
- 《深入理解java虚拟机》Java虚拟机垃圾收集器
- 深入理解 Java 虚拟机-Java 垃圾收集机制
- Java垃圾回收(二)垃圾收集算法---深入理解Java虚拟机
- 微信认证及微社区
- android 的混淆解析
- NSTimer 锁屏以及进入后台不调用的解决方案
- AlertDialog在ActivityGroup中的错误处理
- win8找回经典开始菜单
- 深入理解java虚拟机(七):java垃圾收集分析总结
- Linux:C/Socket多路复用select
- PGSQL删除重复数据
- SRM 610 D2L3:MiningGoldEasy,dp
- android ActionBar详解
- E9 Ubuntu内核编译的简洁方法
- Java进击(二) I/O流
- 从一个COM接口的Dll文件创建接口 - 模拟CoCreateInstance
- mysql---innodb(1)