JVM内存的系统级调优主要目的是减少 Minor GC的频率和 Full GC的次数,过多的 Minor GC 和 Full GC 是会占用很多的系统资源,影响系统的吞吐量。
1. 年轻代分三个区,一个 Eden区,两个 Survivor区(from 和 to),可以通过 --XX:SurvivorRatio 调整比例。
默认 --XX:SurvivorRatio=8,表示 Survivor区与 Eden区的大小比值是 1:1:8,在 MinorGC过程中,如果 survivor 空间不够大,不能够存储所有从 eden 空间和 from survivor 空间复制过来的活动对象,溢出的对象会被复制到 old代,溢出迁移到 old代,会导致 old 代的空间快速增长。
2. 大部分对象先在 Eden 区中申请内存
可以通过设置 -XX:PreTenureSizeThreshold 大小,令大于这个值的对象直接保存到年老代,避免在 Eden区和 Survivor 区之间频繁地通过复制算法回收内存。
3. 当 Eden区满时,无法为新的对象分配内存时,会进行 Minor GC对其回收无用对象占用的内存,如果还有存活对象,则将存活的对象复制到 Survivor From;从 Eden区存活下来的对象,就会被复制到 To区,经历一定的次数 Minor GC后,还存活的对象,将被复制到“年老区(Tenured)”
Minor默认15次,可通过 --XX:MaxTenuringThreshold参数调整年轻代回收次数,防止对象过早进入年老代,降低老年代溢出的可能性。
4. 年轻代和年老代的默认比例是 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通知管理员或者执行一些清理工作。
6. --XX:PermSize and --XX:MaxPermSize:设置永久代大小的初始值和最大值。
默认最小值为物理内存的 1/64,最大值为物理内存的 1/16,永久代在堆内存中是一块独立的区域,这里设置的永久代大小并不会被包括在使用参数 --XX:MaxHeapSize 设置的堆内存大小中。
7. --XX:PretenureSizeThreshold:令大于这个设置值的对象直接在老年代中分配。这样做的目的是避免在 Eden区及两个 Survivor区之间发生大量的内存复制。
JVM内存调优详情
最新推荐文章于 2024-04-15 02:45:00 发布