1.参数分类:
JVM
参数主要分为三类:标准参数、X
参数、XX
参数。
https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/java.html
1.1 标准参数:
标准参数中包括功能以及输出的结果都是很稳定的,基本上不会随着JVM
版本的变化发生变化。可以通过-help
指令来查看所有的标准参数:
java -help
查看JDK
版本信息可以使用-version
参数:
java -version
# JDK 版本信息: openjdk version "1.8.0_352" # Java 运行时环境信息: OpenJDK Runtime Environment Corretto-8.352.08.1 (build 1.8.0_352-b08) # JVM 版本信息: OpenJDK 64-Bit Server VM Corretto-8.352.08.1 (build 25.352-b08, mixed mode)
1.2 X 参数:
X
参数:非标准化参数。表示在将来的JVM
版本中可能会发生改变,但是这类以-X
开始的参数变化的比较小。
java -X
注意:如果某个参数=0
,表示使用默认配置,而不是0
。
常见使用的-X
参数:
-Xms
:初始堆内存,默认是当前计算机物理内存的1/64
-Xms1024m
-Xmx
:最大堆内存,默认是当前计算机物理内存的1/4
-Xmx2048m
-Xss
:设置单个线程栈的大小,一般默认为512k-1024k
-Xss512k
-Xmn
:设置年轻代大小。堆内存空间固定的情况下,增大年轻代大小,会导致老年代内存大小减少。
-Xmn512m
1.3 XX 参数:
这是我们日常开发中接触到最多的参数类型。这也是非标准化参数,相对来说不稳定,随着JVM
版本的变化可能会发生变化,主要用于JVM
调优和Debug
。
Boolean
类型:
# 表示启用或者禁用name属性: -XX:[+-]<name>
Key-Value
类型:
# 表示name的属性值为value: -XX:<name>=<value>
常见使用的-XX
参数:
-XX:MetaspaceSize
设置元空间大小(元空间(Java8才有)的本质和永久代类似,都是对 JVM 规范中的方法区的实现,不过元空间于永久代之间最大区别在于,元空间并不在虚拟中,而是使用本地内存,因此默认情况下,元空间的大小仅受本地内存限制)
元空间默认(21MB)比较小,我们可以调大一点(比如256MB)
-XX:+PrintGCDetails
用于查看详细的 GC 日志信息
设置 JVM 参数为: -Xms10m -Xmx10m -XX:+PrintGCDetails,然后故意使用较大的内存,就可以看到OOM信息以及GC日志信息
常用配置:
控制台部分GC日志:
YGC日志信息解读:
FGC日志信息解读:
-XX:SurvivorRatio
设置新生代中 eden 和 S0/S1 空间比例
默认 -XX:SurvivorRatio=8,Eden : S0 : S1 = 8 : 1 : 1
-XX:NewRatio
配置新生代和老年代在堆中的占比
默认 -XX:NewRatio=2 新生代占1,老年代占2,新生代占整个堆的 1/3
-XX:NewRatio=4 新生代占1,老年代占4
-XX:MaxTenuringThreshold
设置垃圾最大年龄,默认15,最大也是15
-XX:MaxDirectMemorySize
最大直接内存,即本地内存,一般默认是本机物理内存的1/4,其实就是最大堆内存
常见的OOM错误
java.lang.StackOverflowError
产生原因:在一个函数中调用自己就会产生这个错误
java.lang.OutOfMemoryError : Java heap space
产生原因:new 一个很大对象
java.lang.OutOfMemoryError : GC overhead limit exceeded
产生原因:执行垃圾收集的时间比例太大, 有效的运算量太小,默认情况下,,如果GC花费的时间超过 98%, 并且GC回收的内存少于 2%, JVM就会抛出这个错误。
java.lang.OutOfMemoryError : Direct buffer memory
产生原因:直接/堆外内存满了,和GC无关(GC不会管堆外内存),可能是直接分配堆外内存的程序导致的
java.lang.OutOfMemoryError : unable to create new native thread
这个问题经常问,因为和高并发、多线程有关
产生原因:一个进程创建线程太多了,Linux系统默认单个进程创建的最大线程数是1024个
java.lang.OutOfMemoryError : Metaspace
产生原因:元空间满了,元空间用的本地内存