首页 > 代码库 > JVM调优-计算活跃数据大小
JVM调优-计算活跃数据大小
活跃数据,有时候也叫做存活数据,指应用处于稳定运行状态下,在Java堆里面长期存活的对象的大小。换一句话说,就是应用在稳定运行的状态下,FullGC之后,Java堆的所占的空间大小(内存的占用情况)。
1、活跃数据计算的重要性
Java应用的活跃数据大小的计算,是我们进行JVM调优的一个必备的过程,如果我们不知道这个系统的活跃数据有多少,那么我们怎么给他分配合适的内存?因此,计算活跃数据大小是JVM调优的的重要一步。
Java应用的活跃数据大小可以通过GC日志收集。
活跃数据主要包括两块,老年代的大小和永久代的大小。
2、活跃数据的查看方式
为了更好的计算应用程序的活跃数据大小,最好在多次FULLGC之后再查看JAVA堆的占用情况。但是话又要说回来,很多JVM因为内存设置的不合理,导致大量FULL GC的出现,如果用这个数据来指导调优,会陷入越调试越乱的怪圈;
与此同时,有的系统已经经过了优化,或者碰上了好运气,随便设置一个参数,结果刚刚好,FULLGC从来没有发生过,这样的情况,通过GC日志收集几乎就看不到FULL GC发生。这种情况,可以使用一些工具,强制进行垃圾回收,触发FULLGC事件。比如用JDK自带的JConsole触发。
计算活跃数据是我JVM调优的核心。
首先看一个样例,在实际应用用要找到FULL GC比较容易,但是整个系统搬上来比较麻烦,写一个简单的例子,模拟FULLGC出现的情况。
3、计算活跃数据(模拟FULL GC)的源代码
packagecom.gc;
importjava.util.ArrayList;
importjava.util.List;
/**
* 简单的模拟FULLGC,用来计算活跃数据大小
* 参数:-Xms30m-Xmx60m -XX:+UseParallelGC -XX:+PrintGCDetails
* @author 范芳铭
*/
publicclass EasyActiveData {
public byte[] placeHolder = newbyte[1024 * 1024]; //占位符 1M
public static void main(String[] args)throws Exception{
activeData();
}
private static void activeData() throwsException{
List<EasyActiveData>list_a = new ArrayList<EasyActiveData>();
List<EasyActiveData>list_b = new ArrayList<EasyActiveData>();
for(int j=0; j < 25;j ++){
EasyActiveDataserial = new EasyActiveData();
list_a.add(serial);
}
Thread.sleep(100);//停顿下
for(int j=0; j < 30;j ++){
EasyActiveDataserial = new EasyActiveData();
list_b.add(serial);
}
Thread.sleep(100);//停顿下
while(true){
EasyActiveDataserial = new EasyActiveData();
serial = list_a.get(0);
serial = null;
serial =list_b.get(0);;
Thread.sleep(100);//停顿10毫秒
}
}
}
运行参数
-Xms30m 启动内存
-Xmx60m 最大内存
-XX:+UseParallelGC 选用的垃圾回收方式
-XX:+PrintGCDetails 打印GC明细
4、运行结果
[Full GC [PSYoungGen: 48K->0K(4416K)][PSOldGen: 30879K->30879K(39488K)] 30927K->30879K(43904K) [PSPermGen:2086K->2086K(12288K)], 0.0028453 secs] [Times: user=0.00 sys=0.00, real=0.00secs]
[GC [PSYoungGen:4098K->48K(4416K)] 34977K->35023K(43904K), 0.0035403 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen:48K->0K(4416K)] [PSOldGen: 34975K->34975K(44672K)]35023K->34975K(49088K) [PSPermGen: 2086K->2086K(12288K)], 0.0026413 secs][Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen:4098K->48K(4416K)] 39073K->39119K(49088K), 0.0028593 secs] [Times:user=0.00 sys=0.06, real=0.00 secs]
[GC [PSYoungGen:4146K->48K(4416K)] 43217K->43219K(49088K), 0.0035522 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen:48K->0K(4416K)] [PSOldGen: 43171K->43152K(54272K)]43219K->43152K(58688K) [PSPermGen: 2086K->2085K(12288K)], 0.0086702 secs][Times: user=0.00 sys=0.00, real=0.01 secs]
[GC [PSYoungGen:4098K->64K(4416K)] 47250K->47312K(58688K), 0.0032439 secs] [Times:user=0.00 sys=0.06, real=0.00 secs]
[GC [PSYoungGen:4162K->64K(4416K)] 51410K->51416K(58688K), 0.0049324 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen:64K->0K(4416K)] [PSOldGen: 51352K->51352K(56768K)] 51416K->51352K(61184K)[PSPermGen: 2085K->2085K(12288K)], 0.0026228 secs] [Times: user=0.00sys=0.00, real=0.00 secs]
[GC [PSYoungGen:4098K->48K(4416K)] 55450K->55496K(61184K), 0.0038392 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen:48K->0K(4416K)] [PSOldGen: 55448K->55448K(56768K)]55496K->55448K(61184K) [PSPermGen: 2085K->2085K(12288K)], 0.0025522 secs][Times: user=0.02 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen:4098K->0K(4416K)] [PSOldGen: 55448K->56472K(56768K)]59546K->56472K(61184K) [PSPermGen: 2085K->2085K(12288K)], 0.0043092 secs]
…
5、结果分析和活跃数据大小计算
[Full GC [PSYoungGen: 48K->0K(4416K)][PSOldGen: 43171K->43152K(54272K)] 43219K->43152K(58688K) [PSPermGen:2086K->2085K(12288K)], 0.0086702 secs] [Times: user=0.00 sys=0.00, real=0.01secs]
[GC [PSYoungGen:4098K->64K(4416K)] 47250K->47312K(58688K), 0.0032439 secs] [Times:user=0.00 sys=0.06, real=0.00 secs]
[GC [PSYoungGen:4162K->64K(4416K)] 51410K->51416K(58688K), 0.0049324 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen:64K->0K(4416K)] [PSOldGen: 51352K->51352K(56768K)]51416K->51352K(61184K) [PSPermGen: 2085K->2085K(12288K)], 0.0026228 secs][Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen:4098K->48K(4416K)] 55450K->55496K(61184K), 0.0038392 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]
从这里可以看出,老年代在慢慢扩大。
[Full GC[PSYoungGen: 64K->0K(4416K)] [PSOldGen: 51352K->51352K(56768K)]51416K->51352K(61184K) [PSPermGen: 2085K->2085K(12288K)], 0.0026228 secs][Times: user=0.00 sys=0.00, real=0.00 secs]
到了这个数据之后,基本稳定下来,大概老年代的空间占用是51352K,老年大的大小基本上就是56768K。永久带占用空间是2085K,大小是12288K。
因此,这个程序的活跃数据大小是:51352K+ 2085K约等于55M
JVM调优-计算活跃数据大小