HotSpot为什么要分为新生代和老年代?
因为有的对象寿命长,有的对象寿命短。应该将寿命长的对象放在一个区,寿命短的对象放在一个区。不同的区采用不同的垃圾收集算法。寿命短的区清理频次高一点,寿命长的区清理频次低一点。提高效率。

为什么要有Survivor区?
如果没有Survivor区,那么Eden每次满了清理垃圾,存活的对象被迁移到老年区,老年区满了,就会触发Full GC,Full GC是非常耗时的,解决办法:

增加老年代内存,那么老年代清理频次减少,但清理一次花费时间更长。
减少老年代内存,老年代一次FullGC时间更少,频率增加。
都不行,只有再加一层Survivor。将Eden区满了的对象,添加到Survivor区,等对象反复清理几遍之后都没清理掉,再放到老年区,这样老年区的压力就会小很多。即Survivor相当于一个筛子,筛掉生命周期短的,将生命周期长的放到老年代区,减少老年代被清理的次数。

选择垃圾收集器相关参数

GC - 图1

  • -XX:+UseParallelGC 新生代 ParallelScavenge + 老年代 ParallelOld,此时不单独指定 SurvivorRatio 虚拟机将会根据当前系统的运行情况调整
  • -XX:+UseParallelOldGC 同上
  • -XX:-UseParallelOldGC 新生代 ParallelScavenge + 老年代 SerialOld

    堆大小相关参数

    Java 堆区域划分

    新生代(Young Generation)和 老年代(Old Generation)是 HotSpot 虚拟机,并且也是业界主流的命名方式

根据 Oracle 官方文档 open in new window,在堆总可用内存配置完成之后,第二大影响因素是为 Young Generation 在堆内存所占的比例。默认情况下,YG 的最小大小为 1310 MB,最大大小为无限制。

1. 设置 Java 堆大小

  • -Xms 设置最小堆空间
  • -Xmx 设置最大堆空间

    2. 设置新生代大小(包括Eden、From Survivor0、To Survivor1)

    1. -Xmn 设置新生代的大小(默认 Eden : From : To = 8 : 1 : 1)
    2. -XX:NewRatio= 设置新生代(包括Eden和两个Survivor区)与老年代的比值
    3. -XX:NewSize-XX:MaxNewSize 指定新生代的最小值和最大值(JDK 1.3和1.4)

触发 GC 的相关参数

  • -XX:MaxTenuringThreshold 来设置对象晋升到老年代的年龄阈值;

方法区相关参数设置

从Java 8开始,如果我们没有指定 Metaspace 的大小,随着更多类的创建,虚拟机会耗尽所有可用的系统内存(永久代并不会出现这种情况)。
JDK 1.8 之前永久代还没被彻底移除的时候通常通过下面这些参数来调节方法区大小

1. 设置永久代大小(Java7 及以前使用)

  • -XX:PermSize 设置永久代初始大小
  • ‑XX:MaxPermSize 设置永久代最大可分配空间,超过这个值将会抛出 OutOfMemoryError 异常:java.lang.OutOfMemoryError: PermGen

JDK 1.8 的时候,方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是本地内存。

2. 设置元空间大小(Java 8 及以后使用):

  • -XX:MaxMetaspaceSize 设置最大元空间大小,默认值为 unlimited,表示它只受系统内存的限制;
  • -XX:MetaspaceSize 定义元空间的初始大小,如果未指定此标志,则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小,可能耗尽所有可用的系统内存

    调试程序相关参数

    -XX:+PrintGCDetails 查看 GC 详细信息,没有 GC 也会打印堆栈的分布情况,和下面参数配合使用更好
    -XX:+PrintHeapAtGC 查看 GC 前后的堆、方法区可用容量变化,没 GC 不会打印任何东西,
    -XX:+PrintTenuringDistribution 在每次新生代GC时,打印出幸存区中对象的年龄分布
    -XX:+PrintGCDateStamps 输出GC的时间
    -XX:+UseGCLogFileRotation
    -XX:NumberOfGCLogFiles=< number of log files >
    -XX:GCLogFileSize=< file size >[ unit ]
    -Xloggc:/path/to/gc.log

默认参数

-XX:InitialHeapSize=267361856
-XX:MaxHeapSize=4277789696
-XX:+PrintCommandLineFlags
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:-UseLargePagesIndividualAllocation
-XX:+UseParallelGC

添加虚拟机参数 VM argument

  1. -verbose:gc //在控制台输出GC情况
  2. -XX:+PrintGCDetails //在控制台输出详细的GC情况
  3. -Xloggc: filepath //将GC日志输出到指定文件中

image.png