4

Java性能优化之针对分代垃圾回收调整

[TOC]


JVM内存的系统级的调优主要的目的是减少Minor GC的频率和Full GC的次数,过多的Minor GC和Full GC是会占用很多的系统资源,影响系统的吞吐量。

针对分代垃圾回收调整部分参数

  • 年轻代分三个区,一个Eden区,两个Survivor区(from和to区),可以通过-XXSurvivorRatio调整比例

    作用:默认-XX:SurvivorRatio=8,表示Survivor区与Eden区的大小比值是1:1:8,

    在MinorGC过程,如果survivor空间不够大,不能够存储所有的从eden空间和from suvivor空间复制过来活动对象,溢出的对象会被复制到old代,

    溢出迁移到old代,会导致old代的空间快速增长。

  • 大部分对象在先在Eden区中申请内存

    作用:可以通过设置-XX:PreTenureSizeThreShold大小,令大于这个值的对象直接保存到年老代,避免在Eden区与Survivor区之间频繁地通过复制算法回收内存

  • 当Eden区满时,无法为新的对象分配内存时,会进行Minor GC对其回收无用对象占用的内存,如果还有存活对象,则将存活的对象复制到Survivor From区(两个中Survivor对称);然后从Eden区存活下来的对象,就会被复制到From,当这个From区满时,此区的存活对象将被复制到To区,接下来Eden区存活下来的对象就会被复制到To区,经历一定的次数Minor GC后,还存活的对象,将被复制“年老区(Tenured)”。

    作用:Minor默认15次,可通过-MaxTenuringThreshold参数调整年轻代回收次数,防止对象过早进入年老代,降低年老代溢出的可能性

  • 年轻代和年老代的默认比例为1:2,即年轻代占堆内存的1/3,年老代占2/3,可调整-XX:NewRatio的大小设置年轻和年老的比例。

    作用:默认-XX:NewRatio=2,即young:tenured=1:2,适当调整年轻代大小,可以一定层度上较少Full GC出现的概率

其余性能调优常用参数设置

  1. -Xms and -Xmx (or: -XX:InitialHeapSize and -XX:MaxHeapSize):指定JVM的初始和最大堆内存大小,两值可以设置相同,以避免每次垃圾回收完成后JVM重新分配内存。
  2. -Xmn:设置年轻代大小。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
  3. -Xss:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
  4. -XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath:让JVM在发生内存溢出时自动的生成堆内存快照(堆内存快照文件有可能很庞大,推荐将堆内存快照生成路径指定到一个拥有足够磁盘空间的地方。)
  5. -XX:OnOutOfMemoryError:当内存溢发生时,我们甚至可以可以执行一些指令,比如发个E-mail通知管理员或者执行一些清理工作($ java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError ="sh ~/cleanup.sh" MyApp)
  6. -XX:PermSize and -XX:MaxPermSize:设置永久代大小的初始值和最大值(默认:最小值为物理内存的1/64,最大值为物理内存的1/16,永久代在堆内存中是一块独立的区域,这里设置的永久代大小并不会被包括在使用参数-XX:MaxHeapSize 设置的堆内存大小中)
  7. -XX:PretenureSizeThreshold :令大于这个设置值的对象直接在老年代分配。这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存复制

石志远
572 声望62 粉丝