gc实例与gc报告的阅读
gc报告的阅读
首先我们看一条gc报告
D:\杂项\java>java -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:SurvivorRatio=8 testAllocation [GC[DefNew: 7492K->980K(9216K), 0.0034913 secs] 7492K->7124K(19456K), 0.0037735 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap def new generation total 9216K, used 3358K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000) eden space 8192K, 29% used [0x00000000f9a00000, 0x00000000f9c52728, 0x00000000fa200000) from space 1024K, 95% used [0x00000000fa300000, 0x00000000fa3f5100, 0x00000000fa400000) to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) tenured generation total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000) the space 10240K, 60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000) compacting perm gen total 21248K, used 2471K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) the space 21248K, 11% used [0x00000000fae00000, 0x00000000fb069d58, 0x00000000fb069e00, 0x00000000fc2c0000) No shared spaces configured.
先看java运行的几个参数
-Xms20m -Xmx20m -Xmn10m说明堆的大小固定不变,为20m,其中年轻代为10m
-XX:+PrintGCDetails 让虚拟机打印出gc日志,最后输出当前内存各个区域的使用情况。注意,这是两部分内容,一个是gc日志,一个是内存使用情况。
-XX:+UseSerialGC 使用-XX:+UseSerialGC可以使用Serial+Serial Old模式运行进行内存回收(这也是虚拟机在Client模式下运行的默认值)
-XX:SurvivorRatio=8 说明eden区与一个Survivor区的大小比例为8。
至于[GC[DefNew: 7492K->980K(9216K), 0.0034913 secs] 7492K->7124K(19456K), 0.0037735 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]具体是什么意思
大家参阅Java GC 日志详解
我就补充一点:日志开头的[GC和[Full GC说明了此次垃圾收集的停顿类型,而不是用来区分新生代GC还是老年代GC。
我们看几个实例
D:\杂项\java>type testAllocation2.java
/**
*
* -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8
*
*/
public class testAllocation2{
private static int _1m=1024*1024;
public static void main(String[] args) {
byte[] all1,all2,all3,all4,all5;
all1=new byte[_1m * 2];
all2=new byte[_1m * 2];
all3=new byte[_1m * 2];
all4=new byte[_1m * 4];
}
}
D:\杂项\java>javac testAllocation2.java
D:\杂项\java>java -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8 testAllocation2
Heap
PSYoungGen total 9216K, used 7143K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 87% used [0x00000000ff600000,0x00000000ffcf9ff8,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
ParOldGen total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000010,0x00000000ff600000)
PSPermGen total 21504K, used 2468K [0x00000000f9a00000, 0x00000000faf00000, 0x00000000fec00000)
object space 21504K, 11% used [0x00000000f9a00000,0x00000000f9c691d0,0x00000000faf00000)
D:\杂项\java>
上面的代码是我从<<深入理解java虚拟机>>第二章中引过来的。但是并没有发生gc呀?
花了好长时间,才知道得加上一个参数。
-XX:+UseSerialGC
不是说默认就是这个参数么?
我的java版本:
D:\杂项\java>java -version java version "1.7.0_67" Java(TM) SE Runtime Environment (build 1.7.0_67-b01) Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
搞不清楚了。
我们加上这个参数
D:\杂项\java>java -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:SurvivorRatio=8 testAllocation2 [GC[DefNew: 6980K->468K(9216K), 0.0034679 secs] 6980K->6612K(19456K), 0.0037547 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap def new generation total 9216K, used 4894K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000) eden space 8192K, 54% used [0x00000000f9a00000, 0x00000000f9e527b0, 0x00000000fa200000) from space 1024K, 45% used [0x00000000fa300000, 0x00000000fa3750f0, 0x00000000fa400000) to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) tenured generation total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000) the space 10240K, 60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000) compacting perm gen total 21248K, used 2471K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) the space 21248K, 11% used [0x00000000fae00000, 0x00000000fb069cf8, 0x00000000fb069e00, 0x00000000fc2c0000) No shared spaces configured. D:\杂项\java>
OK,发生gc了。
all1,all2,all3加入后,eden区域已经被占了6m了,本来就只有8m,all4的4m一来,马上就发生Minor gc
6m的对象中没有任何一个能放入一个survivor区,那没办法了,6m的对象直接进入老年代。
tenured generation total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
the space 10240K, 60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000)
能说明这个问题。
那么all4呢,它的4m,就还是放到eden区。
我们再看一个例子。
private static int _0_5M=1024*512;
public static void main(String[] args) {
byte[] all1,all2,all3,all4,all5;
all1=new byte[1*_0_5M];
all2=new byte[4*_0_5M];
all3=new byte[4*_0_5M];
all4=new byte[4*_0_5M];
all5=new byte[4*_0_5M];
}
结果
D:\杂项\java>java -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:SurvivorRatio=8 testAllocation [GC[DefNew: 7492K->980K(9216K), 0.0036395 secs] 7492K->7124K(19456K), 0.0038973 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap def new generation total 9216K, used 3358K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000) eden space 8192K, 29% used [0x00000000f9a00000, 0x00000000f9c52728, 0x00000000fa200000) from space 1024K, 95% used [0x00000000fa300000, 0x00000000fa3f5100, 0x00000000fa400000) to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) tenured generation total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000) the space 10240K, 60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000) compacting perm gen total 21248K, used 2471K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) the space 21248K, 11% used [0x00000000fae00000, 0x00000000fb069d00, 0x00000000fb069e00, 0x00000000fc2c0000) No shared spaces configured. D:\杂项\java>
all5产生时发生了minor gc,与上面的例子不同的时,最后:all2,all3,all4进入了老年代,而all1与all5共2.5m进入了eden区。
那怎么survivor还占用了95%,这个我估计是堆里的其他数据。大家忽略之。
感谢glt
参考资料
http://blog.csdn.net/alivetime/article/details/6895537
gc实例与gc报告的阅读的更多相关文章
- GC参考手册 —— GC 调优(工具篇)
JVM 在程序执行的过程中, 提供了GC行为的原生数据.那么, 我们就可以利用这些原生数据来生成各种报告.原生数据(raw data) 包括: 各个内存池的当前使用情况, 各个内存池的总容量, 每次G ...
- GC参考手册 —— GC 算法(实现篇)
学习了GC算法的相关概念之后, 我们将介绍在JVM中这些算法的具体实现.首先要记住的是, 大多数JVM都需要使用两种不同的GC算法 —— 一种用来清理年轻代, 另一种用来清理老年代. 我们可以选择JV ...
- System.gc()与Runtime.gc()的区别
(1) GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象 ...
- Java GC工作原理以及Minor GC、Major GC、Full GC简单总结
名词解释: GC:垃圾收集器 Minor GC:新生代GC,指发生在新生代的垃圾收集动作,所有的Minor GC都会触发全世界的暂停(stop-the-world),停止应用程序的线程,不过这个过程非 ...
- Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别
前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出 ...
- -Xloggc:log/gc.log 指定GC log的位置
-Xloggc:log/gc.log指定GC log的位置,以文件输出帮助开发人员分析问题
- Minor GC、Major GC和Full GC之间的区别(转)
在 Plumbr 从事 GC 暂停检测相关功能的工作时,我被迫用自己的方式,通过大量文章.书籍和演讲来介绍我所做的工作.在整个过程中,经常对 Minor.Major.和 Full GC 事件的使用感到 ...
- minor gc 和 full gc
JAVA中关于GC的分析中,需要搞清楚,GC线程在什么时候,对什么东西,做了什么操作. 1-在什么时候 首先需要知道,GC分为minor GC和full GC,JAVA内存分为新生代和老年代,新生代中 ...
- Minor GC、Major GC和Full GC之间的区别
在 Plumbr 从事 GC 暂停检测相关功能的工作时,我被迫用自己的方式,通过大量文章.书籍和演讲来介绍我所做的工作.在整个过程中,经常对 Minor.Major.和 Full GC 事件的使用感到 ...
随机推荐
- MySQL系列教程(一)
摘要 MySQL的最初的核心思想,主要是开源.简便易用.其开发可追溯至1985年,而第一个内部发行版本诞生,已经是1995年.到1998年,MySQL已经可以支持10中操作系统了,其中就包括win平台 ...
- android 小项目------黑名单app
周一的时候,同事在群里问到了黑名单功能,他说网上都没有找到一个完整的,记得谁说过一句,当都没有做过的时候,这就是机会.这几天公司事比较多,只能晚上抽时间写写,直到今天才完整的做出来. 具体效果的话大家 ...
- Vulkan的分层设计
Vulkan驱动层提供了简单高效的API.作为Vulkan API的使用者,我们要严格遵循Vulkan API的使用规则.如果我们违反了这些规则,Vulkan只会返回很少的反馈,它只会报告一部分严重和 ...
- HOG OpenCV 代码片段
直接上代码: #include <opencv2/opencv.hpp> using namespace cv; #include <cmath> using namespac ...
- Openresty 数据共享API.Data Sharing within an Nginx Worker
摘要自:https://github.com/openresty/lua-nginx-module/#data-sharing-within-an-nginx-worker 每nginx worker ...
- Scikit-learn:模型选择Model selection
http://blog.csdn.net/pipisorry/article/details/52250983 选择合适的estimator 通常机器学习最难的一部分是选择合适的estimator,不 ...
- Oracle 11g客户端及PLSQL Developer配置|Instant Client Setup-64位|OraClientLite11g_x86
转载自:http://blog.csdn.net/xiaoyw71/article/details/45311589 Oracle 11g客户端 资源 下载资源,直接解压进行配置 Oracle官方资源 ...
- Xcode7.2使用sqlite3数据库的方法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 之前版本的Xcode是可以直接连接sqlite3的库文件的,但 ...
- Android必知必会--GreenDao缓存
Github版 CSDN版 本篇文章不是介绍GreenDao的配置和基础使用,记录一下GreenDao缓存的问题,帮助遇到同样问题的朋友找到原因和方法,下面是示例: 场景重现 //第一次查询 List ...
- 【IOS 开发】Object - C 语法 之 流程控制
1. if 条件语句 if 表达式 : 表达式是一个 整型 或者 布尔型, 0 或者 FALSE 为 FALSE, 大于 0 为 TRUE; 代码示例 : /********************* ...