笔记链接: 大厂面试视频
# 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
区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概念。