笔记链接: 大厂面试视频
# JVM 的标配参数和 X 参数
官方文档
JVM 的参数类型:
标配参数
-version java -version-help
X参数(了解)
-Xint:解释执行-Xcomp:第一次使用就编译成本地代码-Xmixed:混合模式
# VM 的 XX 参数之布尔类型
公式: -XX:+ 或者 - 某个属性值( + 表示开启, - 表示关闭)
如何查看一个正在运行中的 java 程序,它的某个 jvm 参数是否开启?具体值是多少?
1 | jps -l 查看一个正在运行中的java程序,得到Java程序号。 |
Case
是否打印
GC收集细节
1 | -XX:-PrintGCDetails |
是否使用串行垃圾回收器
1 | -XX:-UseSerialGC |
# JVM 的 XX 参数之设值类型
公式: -XX : 属性 key= 属性值 value
Case
1 | -XX:MetaspaceSize=128m |
# VM 的 XX 参数之 XmsXmx 坑题
两个经典参数:
1 | -Xms等价于-XX:InitialHeapSize,初始大小内存,默认物理内存1/64 |
# JVM 盘点家底查看初始默认
查看初始默认参数值
1 | -XX:+PrintFlagsInitial |
公式: java -XX:+PrintFlagsInitial
查看修改更新参数值
1 | -XX:+PrintFlagsFinal |
公式: java -XX:+PrintFlagsFinal
= 表示默认, := 表示修改过的。
# JVM 盘点家底查看修改变更值
PrintFlagsFinal 举例,运行 java 命令的同时打印出参数
1 | java -XX:+PrintFlagsFinal -XX:MetaspaceSize=512m HelloWorld |
打印命令行参数
1 | -XX:+PrintCommandLineFlags |
1 | (base) ➜ ~ java -XX:+PrintCommandLineFlags -version |
# 堆内存初始大小快速复习
JDK 1.8 之后将最初的永久代取消了,由元空间取代。
在 Java8 中,永久代已经被移除,被一个称为元空间的区域所取代。元空间的本质和永久代类似。
元空间 ( Java8 ) 与永久代 ( Java7 ) 之间最大的区别在于:永久带使用的 JVM 的堆内存,但是 Java8 以后的元空间并不在虚拟机中而是使用本机物理内存。
因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入 native memory ,字符串池和类的静态变量放入 java 堆中,这样可以加载多少类的元数据就不再由 MaxPermSize 控制,而由系统的实际可用空间来控制。
1 | public class JVMMemorySizeDemo { |
输出结果:
# 常用基础参数栈内存 Xss 讲解
设置单个线程栈的大小,一般默认为 512k~1024K
等价于 -XX:ThreadStackSize
-XX:ThreadStackSize=size
Sets the thread stack size (in bytes). Append the letter k or K to indicate kilobytes, m or M to indicate megabytes, g or G to indicate gigabytes. The default value depends on virtual memory.
The following examples show how to set the thread stack size to 1024 KB in different units:
-XX:ThreadStackSize=1m
-XX:ThreadStackSize=1024k
-XX:ThreadStackSize=1048576
This option is equivalent to-Xss. 文档
# 常用基础参数元空间 MetaspaceSize 讲解
-Xmn:设置年轻代大小-XX:MetaspaceSize设置元空间大小
元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制
典型设置案例
1 | -Xms128m -Xmx4096m -Xss1024k -XX:MetaspaceSize=512m -XX:+PrintCommandLineFlags -XX:+PrintGCDetails-XX:+UseSerialGC |
# 常用基础参数 PrintGCDetails 回收前后对比讲解
-XX:+PrintGCDetails 输出详细 GC 收集日志信息
设置参数 -Xms10m -Xmx10m -XX:+PrintGCDetails 运行以下程序
1 | import java.util.concurrent.TimeUnit; |
输出结果:
1 | [GC (Allocation Failure) [PSYoungGen: 778K->480K(2560K)] 778K->608K(9728K), 0.0029909 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] |
# 常用基础参数 SurvivorRatio 讲解
调节新生代中 eden 和 S0、S1 的空间比例,默认为 -XX:SuriviorRatio=8,Eden:S0:S1 = 8:1:1
假如设置成 -XX:SurvivorRatio=4 ,则为 Eden:S0:S1 = 4:1:1
SurvivorRatio 值就是设置 eden 区的比例占多少, S0 和 S1 相同。
# 常用基础参数 NewRatio 讲解
配置年轻代 new 和老年代 old 在堆结构的占比
默认: -XX:NewRatio=2 新生代占 1 ,老年代 2 ,年轻代占整个堆的 1/3
-XX:NewRatio=4: 新生代占 1 ,老年代占 4 ,年轻代占整个堆的 1/5 ,
NewRadio 值就是设置老年代的占比,剩下的 1 个新生代。
新生代特别小,会造成频繁的进行 GC 收集。
# 常用基础参数 MaxTenuringThreshold 讲解
晋升到老年代的对象年龄。
SurvivorTo和SurvivorFrom 互换,原 SurvivorTo 成为下一次 GC 时的 SurvivorFrom 区,部分对象会在 From 和 To 区域中复制来复制去,如此交换 15 次(由 JVM 参数 MaxTenuringThreshold 决定,这个参数默认为 15 ),最终如果还是存活,就存入老年代。
这里就是调整这个次数的,默认是 15,并且设置的值 在 0~15 之间。
-XX:MaxTenuringThreshold=0 :设置垃圾最大年龄。如果设置为 0 的话,则年轻对象不经过 Survivor 区,直接进入老年代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大的值,则年轻代对象会在 Survivor 区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概念。