JVM调优分享-(概要+例子)
来源:互联网 发布:网络ip地址怎么修改 编辑:程序博客网 时间:2024/06/06 09:57
堆与栈
栈是运行时的单位,而堆是存储的单位
JAVA中堆存的是对象。栈中存的是基本据类型和堆中对象的引用
堆和栈的分离的思想,才使得Java的垃圾回收成为可能
栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰
堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用
堆和栈中,栈是程序运行最根本的东西。程序运行可以没有堆,但是不能没有栈。而堆是为栈进行数据存储服务,说白了堆就是一块共享的内存。不过,正是因为堆和栈的分离的思想,才使得Java的垃圾回收成为可能。
Java中,栈的大小通过-Xss来设置,当栈中存储数据比较多时,需要适当调大这个值,否则会出现java.lang.StackOverflowError异常。常见的出现这个异常的是无法返回的递归,因为此时栈中保存的信息都是方法返回的记录点。
GC时回收的对象
以栈或寄存器中的引用为起点,可以找到堆中的对象,又从这些对象找到对堆中其他对象的引用,这种引用逐步扩展,最终以null引用或者基本类型结束,这样就形成了一颗以Java栈中引用所对应的对象为根节点的一颗对象树,如果栈中有多个引用,则最终会形成多颗对象树。在这些对象树上的对象,都是当前系统运行所需要的对象,不能被垃圾回收。而其他剩余对象,则可以视为无法被引用到的对象,可以被当做垃圾进行回收。
分代垃圾回收
分代垃圾回收采用分治的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收
虚拟机中的共划分为三个代:年轻代(Young Generation)、年老点(Old Generation)和持久代(Permanent Generation)。
所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代分三个区。一个Eden区,两个Survivor区(一般而言)。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)
年老代:
在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。
分代垃圾回收
Serial: 单线程收集器Serial Old:是Serial收集器的老年代版本
单线程的收集器。它的单线程带来的是:只会使用一个CPU,一条收集线程,并且会在工作时暂停所有的工作线程,直到收集结束。
新生代采用复制算法,老年代采用标记整理算法。
ParNew:多线程收集器
Serial收集器的多线程版本,拥有可控制参数(如:-XX:SurvivorRatio, -XX:PretenureSizeThreshold, -XX:HandlePromotionFailure等),收集算法,停顿,对象分配规则,回收策略都和Serial收集器完全一样。
ParNew收集器是许多运行在server模式下的虚拟机中首选的新生代收集器,一个重要的原因是,只有ParNew和Serial收集器能和CMS收集器共同工作
ParNew收集器是使用-XX:+UseConcMarkSweepGC选项的默认新生代收集器。也可以用-XX:+UseParNewGC选项来强制指定它。
ParNew收集器在单CPU环境中不比Serial效果好,甚至可能更差,两个CPU也不一定跑的过,但随着CPU数量的增加,性能会逐步增加。默认开启的收集线程数与CPU数量相同。在CPU数量很多的情况下,可以使用-XX:ParallelGCThreads参数来限制线程数。
两个概念需要区分:
Parallel并行:多垃圾收集线程并行工作,但用户线程仍需等待
Concurrent并发:用户线程和垃圾收集同时进行。
Parallel Scavenge:复制算法收集器
Parallel Scavenge的特点是它的关注点与其他收集器不同,CMS等收集器的关注点尽可能地缩短垃圾收集时用户线程的停顿时间,而ParallelScavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是CPU用于运行用户代码与CPU总消耗时间的比值。
高吞吐量和停顿时间短的策略相比,主要强调任务更快完成,而后者强调用户交互体验。
Parallel Scavenge提供两个参数控制垃圾回收停顿时间:-XX:MaxGCPauseMillis和-XX:GCTimeRatio
MaxGCPauseMillis允许的值是一个大于零的毫秒数,收集器将尽力保证内存回收话费的时间不超过设定值。GC停顿时间缩小是以牺牲吞吐量和新生代空间来换取的,也就是要使停顿时间更短,垃圾回收的频率会增加。
GCTimeRatio的值是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率。设为19,则允许最大GC时间就占总时间的5%(1/(1+19)),默认99.
也被称为吞吐量优先收集器。
CMS:获取以最短时间停顿为目标的收集器
Concurrent MarkSweep 以获取最短回收停顿时间为目标的收集器,比较理想的应用场景是B/S架构的服务器。
基于标记-清除算法实现,运行过程分成4个步骤:
初始标记(需要stopthe world),标记一下GC Roots能直接关联到的对象,速度很快
并发标记,进行GCRoots Tracing的过程。
重新标记(需要stopthe world),为了修正并发标记时用户继续运行而产生的标记变化,停顿时间比初始标记长,远比并发标记短。
并发清除
G1收集器
G1. Garbage first,尚在研发阶段,使用标记-整理算法,精确控制停顿,极力避免全区域垃圾收集。前面的收集器进行的收集范围都是整个新生代或老年代,而G1将整个JAVA堆划分为多个大小固定的独立区域,跟踪这些区域里面的垃圾堆积程度,在后台维护一个优先列表,每次在允许的收集时间里,优先回收垃圾最多的区域。
JVM调优定义
基于JVM的内存管理和垃圾回收机制的特性,通过控制堆内存的各个部分的比例和GC策略来实现JVM性能或业务指标的最优化。
典型应用中,对象的生命周期
横轴是以分配的字节数度量度量的对象生存期。纵轴方向计算的字节数是相应生存期对象的总字节数。左侧的峰值表示分配之后不久就被回收的对象
GC性能对整个系统性能的影响
如何调优
JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数,过多的GC和Full GC是会占用很多的系统资源(主要是CPU),影响系统的吞吐量。特别要关注Full GC,因为它会对整个堆进行整理,导致Full GC一般由于以下几种情况:
调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创建过大的对象及数组避免直接在旧生代创建对象
增大Perm Gen空间,避免太多静态对象
控制好新生代和旧生代的比例
垃圾回收不要手动触发,尽量依靠JVM自身的机制
调优手段主要是通过控制堆内存的各个部分的比例和GC策略来实现
各部分比例不良设置会导致什么后果:
一是新生代GC次数非常频繁,增大系统消耗;二是导致大对象直接进 入旧生代,占据了旧生代剩余空间,诱发Full GC
一是新生代设置过大会导致旧生代过小(堆总量一定),从而诱发Full GC;二是新生代GC耗时大幅度增加。一般说来新生代占整个堆1/3比 较合适
导致对象从eden直接到达旧生代,降低了在新生代的存活时间
导致eden过小,增加了GC频率
实例:
新对象预留在新生代
public static void main (String args[]){byte [] b1,b2,b3,b4;b1= new byte [1024*1024];b2= new byte [1024*1024];b3= new byte [1024*1024];b4= new byte [1024*1024];}
例2:
大对象直接进入老年代
-XX:PretenureSizeThreshold=1000000
public static void main(String args[]){byte [] b1;b1= new byte[1024*1024];}
使用-XX:+PrintGCDetails -Xmx20M -Xms20M和-XX:+PrintGCDetails -Xmx20M -Xms20M-XX:PretenureSizeThreshold=1000000
例3:
稳定的堆大小可以减少GC的次数
GC时间长
-XX:MinHeapFreeRatio=40
-XX:MaxHeapFreeRatio=50
public static void main(String args[]) throws InterruptedException{Vector v =new Vector();while(true){byte [] b = new byte [1024*1024];v.add(b);if(v.size() ==10 ){v = new Vector();}Thread.sleep(1000);}}
- JVM调优分享-(概要+例子)
- jvm调优经验分享
- JVM调优经验分享
- 一次JVM内存调优的分享
- 一次JVM内存调优的分享
- JVM生命周期概要
- JVM 原理概要
- JVM调优分享-(调优的关键点)
- 分享:JVM及其性能调优的PPT,欢迎交流
- JVM分享
- JVM 垃圾回收原理概要
- JVM 垃圾回收原理概要
- JVM(一)java的执行概要
- JAVA总结系列(一)JVM概要
- JVM的例子
- nodeJS入门例子一概要(Synopsis)
- Hadoop性能调优概要说明
- jvm系列(十一):JVM演讲PPT分享
- Learning the parts of object by NMF
- HDU 1576 A/B
- <<OCM实验选讲>> 第五课 数据备份恢复实验
- Struts2标签
- cocos2dx场景切换小例子
- JVM调优分享-(概要+例子)
- dede用户登录时,跳转到提示页时报404错误
- opencv 关于 cvCalcHist的含义(1)
- unix高级环境编程 例子 代码实现练习 第七章:进程环境
- 序言
- 二叉树的层次遍历
- ARCH UEFI 想说爱你不容易
- 计科1111-1114班第一周讲义、课外作业(截止日期:2014年3月12日23点-周三晚,学委飞信通知同学)
- Jxl.jar操作excel使用总结