jvm的调优主要是对jvm的堆参数做些相应的配置,具体得根据实际情况,下面列出一些参数的定义,方便以后在具体做调优时的参考。
-Xms初始堆大小
默认物理内存的1/64(<1GB)
-Xmx最大堆大小
默认物理内存的1/4(<1GB),实际中建议不大于4GB。太大的话FGC会时间很长,这样会有问题,同时也会带来其他很多奇怪的问题。
一般建议设置 -Xms=-Xmx
配置相等的好处是避免每次gc后,调整堆的大小,减伤系统内存分配开销。其实不必要动态伸缩,因为这样也会消耗系统资源。
整个堆大小=年轻代大小+年老代大小+持久代大小
spring框架中默认持久代PermGen为256MB 由于存在反射的原因,可能会out of Mem。解决办法,调大就可以了,调大1倍或更多。
新生代=1个eden区+2个survivor区(S0 和 S1)
-Xmn 配置年轻代大小(1.4 or lator)
-XX:NewSize,-XX:MaxNewSize(设置年轻代大小(for 1.3 or 1.4)老版本这样设置)
默认大小为整个堆的3/8
-XX:NewRatio
年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)
设置了Xms=Xmx 并且设置了Xmn的情况下,该参数不需要设置 ,一般用的比较少
举例 假设整个堆大小100M 持久代10M -XX:NewRatio值为7的话 则 年轻代 + 年老代 =100M - 10M ,年轻代/年老代=7。
-XX:SurvivorRatio
Eden区与Survivor区的大小比值,默认设置为8。则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10,即S0: S1:Eden=1:1:8
新生代用来存放JVM刚分配Java对象
年老代=整个堆大小-年轻代-持久代 无参数配置,是通过减法得出的
年轻代中经过垃圾回收没有回收掉的对象,被复制到老年代
老年代存储的对象比年轻代年龄大的多,不乏大对象(例如缓存)
新建的对象也有可能直接进入老年代
大对象,可通过启动参数设置-XX:PrertenureSizeThreshold=1024(单位为字节,默认为0)来代表超过多大时就不在新生代分配,而是直接在年老代分配。例如配置文件 但是也不建议使用
大的数组对象,切数组中无引用外部对象
年老代大小无配置
持久代=整个堆大小-年轻代大小-年老代大小
-XX:PermSize -XX:MaxPermSize
设置持久代的大小。一般推荐把-XX:PermSize设置成-XX:MaxPermSize相同的值,因为持久代大小的调整,或者说动态伸缩,也会导致资源消耗。
存放Class、Method元信息,其大小与项目规模、类、方法的数量有关。一般设置128M足够了,设置原则是预存30%的空间。由于部分类库并非启动初始化时加载,而是在运行时加载。例如初始化持久代大小128M,初始化时100M,如果随着程序运行加载总的加起来超过128M。持久代就out o fmem了,系统就挂了。
持久代的回收方式。
常量池中的常量,无用的类信息,常量的回收很简单,没有引用了就可以被回收
对于无用的类进行回收,必须保证3点:
引用计数算法(已经不用了)
根搜索算法
从GC ROOTs开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
复制算法 采用从根集合扫描(GCroot),将存活对象复制到一块新的,没有使用过的空间中(S0或S1)。用于新生代内存回收 E区 到S0或S1的算法
标记清除算法
标记整理压缩算法
是一个单线程收集器,只能使用一个CPU或一个线程去完成垃圾回收;在进行垃圾回收时,必须暂停所有其他工作线程,直到回收完成
缺点 Stop-The-World
优点 简单。对于单CPU情况,由于没有多线程交互开销,反而可以更高效。是client模式下默认的新生代收集器。
-XX:+UseSerialGC开启
1.Serial New + Serial Old的收集器组合进行内存回收
2.使用复制算法
3.独占式垃圾回收
一个线程进行GC,串行。其他工作线程暂停。
-XX:+UseSerialGC开启
1.Serial New + Serial Old的收集器组合进行内存回收
2.使用标记-压缩算法
3.串行的、独占式的垃圾回收器
因为内存比较大,回收比新生代慢
并行回收器也是独占式回收器,回收过程中,应用暂停。但由于使用多线程进行垃圾回收,因此在并发能力较强的CPU上、他产生的停顿时间小于串行回收器。而在单CPU或并发能力较弱的系统上,并行回收器的实际效果不比串行回收器好,由于多线程的压力。实际效果可能比串行回收器差。
1.XX:+UseParNewGC开启
新生代使用并行回收回收器,老年代使用串行回收器
2.-XX:ParallelGCThreads 指定线程数
默认建议与CPU数量一致,避免过多的线程数影响垃圾回收性能。
3.使用复制算法
4.并行、独占垃圾回收器
1.吞吐量优先回收器
关注CPU吞吐量,即运行用户代码的时间/总时间,比如JVM运行100分钟,其中运行用户代码99分钟,垃圾回收1分钟,吞吐量为99%。这种回收器能最高效率的利用CPU,适合运行后台运算。
2.-XX:+UseParalelGC 开启
使用Parallel Scavenge+Serial Old回收器组合回收垃圾,这也是Server模式下的默认值
3.-XX:GCTimeRatio
设置用户执行时间占总时间的比例,默认99 即1%时间用来进行垃圾回收
4.-XX:MaxGCPauseMillis
设置GC的最大停顿时间
5.使用复制算法
1.-XX:+UseParallelOldGC 开启
使用Parallel Scavenge + Parallel Old组合进行垃圾回收
2.使用标记整理算法
3.并行的独占式垃圾回收器
运作过程分为4个阶段:
初始标记 值标记GC Roots能直接关联到的对象
并发标记 进行GC RootsTracing的过程
重新标记 修正并发标记期间因用户程序继续运行而导致标记发生改变的那部分对象的标记
并发清除
其中初始标记和重新标记两个阶段任然会Stop-The-World(时间可以比较短),整个过程中耗时最长的并发标记和并发清除过程中收集器都可以和用户线程一起工作。
1.标记-清除算法
同时也是一个使用多线程并发回收的垃圾回收器
2.-XX:ParallelCMSThreads
手工设定CMS的线程数量,CMS默认启动的线程数是((ParallelGCThreads+3)/4)----IO密集型CPUCoreX2 + 1 CPU密集型 CPUCore + 1
3.-XX:+UseConcMarkSweepGC 开启
使用ParNew + CMS + Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现"Concurrent Mode Failure" 失败后的后背收集器使用。失败就FULLGC了 两种回收失败1.还在回收,新生代进来的超过了空间了。2.CMS回收时,新生代进来,导致失败。
4.-XX:CMSInitiatingOccupancyFraction
设置CMS收集器在老年代空间被使用多少后发出垃圾回收,默认68%,仅仅在CMS收集器时有效,例如-XX:CMSInitiatingOccupancyFraction=70。设太高了容易失败,设低了太频繁。
5.-XX:+UseCMSCompactAtFullCollection
由于CMS收集器会产生碎片,此参数设置在垃圾回收器后是否需要一次内存碎片整理过程,仅在CMS收集器时有效。
6.-XX:+CMSFullGCBeforeCompaction
设置CMS收集器在进行若干次垃圾回收后再进行一次内存碎片整理过程,通常与UseCMSCompactAtFullCollection参数一起使用
7.-XX:CMSInitiatingPermOccupancyFraction
设置Perm Gen使用到达多少比率时触发,默认92%
吞吐量 应用花在非GC上的时间百分比
GC负荷 与吞吐量相反,指应用花在GC上的时间百分比
暂停时间 应用花在GC Stop-the-world的时间
GC频率
反映速度 从一个对象变成垃圾到这个对象被回收的时间
一个交互式的应用要求暂停时间越少越好,然而,一个非交互式的应用,希望GC负荷越低越好
一个实时系统对暂停时间和GC负荷的要求,都是越低越好
Cloudhu 个人随笔|built by django|
沪ICP备16019452号-1