JVM重要参数


JVM参数类型

  • 标配参数
    • -version
    • -help
    • java -showversion
  • X参数(了解)
    • -Xint:解释执行
    • -Xcomp:第一次使用就编译成本地代码
    • -Xmixed:混合模式
  • XX参数(重点)
    • Boolean类型
      • 公式:-XX:+ 或者-某个属性 ,+ 表示开启,-表示关闭
      • -XX:-PrintGCDetails:表示关闭了GC详情输出
    • key-value类型
      • 公式:-XX:属性key=属性value
      • -XX:MetaspaceSize=21807104:设置Java元空间的值

查看JVM默认参数

这里可以在终端输入命令查看

  • -XX:+PrintFlagsInitial:查看初始默认值
  • -XX:+PrintFlagsFinal:表示修改以后最终的值,其中 := 表示修改过的, = 表示没有修改过的

如果想看具体某个初始默认值,可以在后面加上 -version |grep JVMParamName

工作中常用JVM配置参数

可以使用-XX:+PrintCommandLineFlags 打印出JVM的默认的简单初始化参数

堆内存相关

Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存

指定堆内存

  • -Xms:初始化堆内存,默认为物理内存的1/64,等价于 -XX:initialHeapSize
  • -Xmx:最大堆内存,默认为物理内存的1/4,等价于-XX:MaxHeapSize

如我们要为 JVM 分配最小 2 GB 和最大 5 GB 的堆内存大小,我们的参数应该这样来写:

-Xms2G -Xmx5G

指定新生代内存

  • -XX:NewSize:初始化新生代内存
  • -XX:MaxNewSize:最大新生代内存

如我们要为新生代分配最小 256m 的内存,最大 1024m 的内存,我们的参数应该这样来写:

-XX:NewSize=256m
-XX:MaxNewSize=1024m

也可以通过-Xmn设置新生代大小,这里NewSize 与 MaxNewSize 设为一致

元空间内存配置

java 8之后方法区就被元空间取代,元空间使用的是本地内存,元空间相关的设置参数有:

  • -XX:MetaspaceSize: 并非和前面一样是设置 Metaspace 的初始大小(是一个常见的误区,后面会解释)
  • -XX:MaxMetaspaceSize:设置 Metaspace 的最大大小

-XX:MetaspaceSize 这个JVM参数是指元空间扩容时触发FullGC的初始化阈值,也是最小的阈值。这里有几个要点需要明确:

  1. 无论-XX:MetaspaceSize配置什么值,Metaspace的初始容量一定是21807104(约20.8m)
  2. Metaspace由于使用不断扩容到-XX:MetaspaceSize参数指定的量,就会发生FullGC;且之后每次Metaspace扩容都会发生FullGC
  3. Meta区容量范围为[20.8m, MaxMetaspaceSize)
  4. 如果MaxMetaspaceSize设置太小,可能会导致频繁FullGC,甚至OOM

垃圾收集相关

垃圾收集器

选择正确的垃圾收集算法可以有效的提高应用程序的稳定性,JVM垃圾收集器声明参数

  • -XX:+UseSerialGC:串行垃圾收集器
  • -XX:+UseParallelGC:并行垃圾收集器
  • -XX:+UseParNewGC:CMS垃圾收集器
  • -XX:+UseG1GC:G1垃圾收集器

GC日志记录

# 必选,打印基本 GC 信息
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
# 打印对象分布
-XX:+PrintTenuringDistribution
# 打印堆数据
-XX:+PrintHeapAtGC
# 打印Reference处理信息
# 强引用/弱引用/软引用/虚引用/finalize 相关的方法
-XX:+PrintReferenceGC
# 打印STW时间
-XX:+PrintGCApplicationStoppedTime

# 可选
# 打印safepoint信息,进入 STW 阶段之前,需要要找到一个合适的 safepoint
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1

# GC日志输出的文件路径
-Xloggc:/path/to/gc-%t.log
# 开启日志文件分割
-XX:+UseGCLogFileRotation
# 最多分割几个文件,超过之后从头文件开始写
-XX:NumberOfGCLogFiles=14
# 每个文件上限大小,超过就触发分割
-XX:GCLogFileSize=50M

GC在新生代

[GC (Allocation Failure) [PSYoungGen: 1972K->504K(2560K)] 1972K->740K(9728K), 0.0156109 secs] [Times: user=0.00 sys=0.00, real=0.03 secs]

Full GC垃圾回收

Full GC大部分发生在老年代

[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 648K->630K(7168K)] 648K->630K(9728K), [Metaspace: 3467K->3467K(1056768K)], 0.0058502 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 

-XX:SurvivorRatio : 调节新生代中 eden 和 S0、S1的空间比例,默认为 -XX:SuriviorRatio=8,Eden:S0:S1 = 8:1:1,加入设置成 -XX:SurvivorRatio=4,则为 Eden:S0:S1 = 4:1:1

参考

  • 尚硅谷 Java 大厂面试题第 2 季
  • JavaGuide(Java面试+学习指南)

文章作者: 不才叶某
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 不才叶某 !
评论
  目录