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

时间: 2024-08-26 11:16:54

JVM调优-计算活跃数据大小的相关文章

JVM调优-初始化空间大小配置

我们得到了活跃数据大小,就可以根据活跃数据的情况,配置我们的初始化空间. 下面是我们的应用在稳定阶段的一段FULLGC.生成的代码在最后. 1.活跃数据示例 [Full GC[PSYoungGen: 64K->0K(4416K)] [PSOldGen: 51352K->51352K(56768K)]51416K->51352K(61184K) [PSPermGen: 2085K->2085K(12288K)], 0.0026228 secs][Times: user=0.00 sy

JVM调优之选择步骤

1. 选择JVM运行模式 a. Client模式:启动快,占用内存少,JIT编译器生成代码的速度也更快. b. Server模式:提供了更复杂的生成代码优化功能,这个功能对服务器应用而言尤其重要.大多数Server模式的JIT的编译优化都要消耗额外的时间以收集更多的应用程序行为信息,为应用程序运行生成更优的代码. c. Tiered Server模式:结合Client和Server运行模式的长处,即快速启动和高效的生成码.  -server -xx:+Tieredcompilation命令.可取

JVM调优基础

一.JVM调优基本流程 1.划分应用程序的系统需求优先级 2.选择JVM部署模式:单JVM.多JVM 3.选择JVM运行模式 4.调优应用程序内存使用 5.调优应用程序延迟 6.调优应用程序吞吐量 二.选择JVM部署模式:单JVM.多JVM 1.单JVM 优点:不需要管理多个JVM,降低管理成本: 应用程序消耗内存数量较少 缺点:存在单点故障,一个JVM失效时,整个系统失效. 2.多JVM 优点:更好的可用性,避免单点故障:更低延迟,因为垃圾收集所产生的停顿是程序延迟的主要原因,多JVM减少了每

转: jvm调优参数总结

JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类 现在比较常用的是分代收集(generational collection,也是SUN VM使用的,J2SE1.2之后引入),即将内存分为几个区域,将不同生命周期的对象放在不同区域里:young generation,tenured generation和permanet generation.绝大部分的objec被分配在young gener

JVM调优知识

一.Java应用服务器 Tomcat.Nginx.Resin.等多种应用服务器,虽然JVM做为容器,提供的是一个Java Web的运行时环境,以支持Servlet/JSP等等这些内容的运行但是我们都很清楚,其本质上是还是一个Java应用程序.现在有哪些java应用服务器呢?商业的有BEA Weblogic Server.IBM Websphere Application Server.Oracle Application Server.Sybase EAServer.免费开源的java应用服务器

JVM调优[转]

JVM调优总结-序 几年前写过一篇关于JVM调优的文章,前段时间拿出来看了看,又添加了一些东西.突然发现,基础真的很重要.学习的过程是一个由表及里,再由里及表的过程.呵呵,所谓的"温故而知新".而真正能走完这个轮回的人,也就能称为大牛或专家了.这个过程可能来来回回,这就是所谓"螺旋上升",而每一次轮回都有新的发现. 这回添加的东西主要集中在基础的一些问题上,还有一些这两年思考的问题.这些问题可能平时我们不会刻意去想,但是真正看清楚了,却发现还是大有裨益的:)希望对大

《JVM调优实战-理论篇》

1 理论篇1.1 多功能养鱼塘-JVM内存大鱼塘O(可分配内存): JVM可以调度使用的总的内存数,这个数量受操作系统进程寻址范围.系统虚拟内存总数.系统物理内存总数.其他系统运行所占用的内存资源等因素的制约.小池塘A(堆内存):JVM运行时数据区域,它为类实例和数组分配的内存.堆可以是固定大小的也可以是可变大小的.其中 Heap = {Old + NEW = { Eden , from, to } }.小池塘B(非堆内存):包括所有线程之间共享的一个方法区域和JVM为优化或内部处理所分配的内存

JVM调优(二)经验参数设置

调优设置具体解析 堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作系统对内存无限制. 在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m. 典型设置: java -Xmx3550m -Xms3550m -Xmn2g -Xss128k  -Xms3550m:设置JVM最大可用堆内存为355

JVM调优总结

一.相关概念 基本回收算法 引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 标记-清除(Mark-Sweep) 此算法执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除.此算法需要暂停整个应用,同时,会产生内存碎片. 复制(Copying) 此 算法把内存空间划为两个相等的区域,每次