一、重要JVM参数
堆内存相关
1.显式指定堆内存–Xms
和-Xmx
-Xms<heap size>[unit]
-Xmx<heap size>[unit]
//如果我们要为 JVM 分配最小 2 GB 和最大 5 GB 的堆内存大小
-Xms2G -Xmx5G
2.显式新生代内存(Young Generation)
-XX:NewSize=<young size>[unit]
-XX:MaxNewSize=<young size>[unit]//果我们要为 新生代分配 最小 256m 的内存,最大 1024m 的内存
-XX:NewSize=256m
-XX:MaxNewSize=1024m新生代分配 256m 的内存(NewSize 与 MaxNewSize 设为一致)-Xmn256m//设置老年代与新生代内存的比值-XX:NewRatio=1
3.显式指定永久代/元空间的大小
从 Java 8 开始,如果我们没有指定 Metaspace 的大小,随着更多类的创建,虚拟机会耗尽所有可用的系统内存(永久代并不会出现这种情况)。
-XX:PermSize=N #方法区 (永久代) 初始大小
-XX:MaxPermSize=N #方法区 (永久代) 最大大小,超过这个值将会抛出 OutOfMemoryError 异常:java.lang.OutOfMemoryError: PermGen
JDK 1.8 的时候,方法区(HotSpot 的永久代)被彻底移除了(JDK1.7 就已经开始了),取而代之是元空间,元空间使用的是本地内存。
-XX:MetaspaceSize=N #设置 Metaspace 的初始大小(是一个常见的误区,后面会解释)
-XX:MaxMetaspaceSize=N #设置 Metaspace 的最大大小
1、Metaspace 的初始容量并不是 -XX:MetaspaceSize
设置,无论 -XX:MetaspaceSize
配置什么值,对于 64 位 JVM 来说,Metaspace 的初始容量都是 21807104(约 20.8m)
2、Metaspace 由于使用不断扩容到-XX:MetaspaceSize
参数指定的量,就会发生 FGC,且之后每次 Metaspace 扩容都会发生 Full GC。
垃圾收集相关
垃圾回收器
JVM 具有四种类型的 GC 实现:
- 串行垃圾收集器
- 并行垃圾收集器
- CMS 垃圾收集器
- G1 垃圾收集器
可以使用以下参数声明这些实现:
-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+UseParNewGC
-XX:+UseG1GC
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
4.处理 OOM
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./java_pid<pid>.hprof
-XX:OnOutOfMemoryError="< cmd args >;< cmd args >"
-XX:+UseGCOverheadLimit
这里有几点需要注意:
- HeapDumpOnOutOfMemoryError 指示 JVM 在遇到 OutOfMemoryError 错误时将 heap 转储到物理文件中。
- HeapDumpPath 表示要写入文件的路径; 可以给出任何文件名; 但是,如果 JVM 在名称中找到一个
<pid>
标记,则当前进程的进程 id 将附加到文件名中,并使用.hprof
格式 - OnOutOfMemoryError 用于发出紧急命令,以便在内存不足的情况下执行; 应该在
cmd args
空间中使用适当的命令。例如,如果我们想在内存不足时重启服务器,我们可以设置参数:-XX:OnOutOfMemoryError="shutdown -r"
。 - UseGCOverheadLimit 是一种策略,它限制在抛出 OutOfMemory 错误之前在 GC 中花费的 VM 时间的比例
二、JDK监控和故障处理工具
JDK 命令行工具
这些命令在 JDK 安装目录下的 bin 目录下:
jps
(JVM Process Status): 类似 UNIX 的ps
命令。用于查看所有 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息;jstat
(JVM Statistics Monitoring Tool): 用于收集 HotSpot 虚拟机各方面的运行数据;jinfo
(Configuration Info for Java) : Configuration Info for Java,显示虚拟机配置信息;jmap
(Memory Map for Java) : 生成堆转储快照;jhat
(JVM Heap Dump Browser) : 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果;jstack
(Stack Trace for Java) : 生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合
JDK 可视化分析工具
- JConsole
- JConsole是一个内置Java性能分析器,基于JMX(Java Management Extensions)的可视化监视、管理工具。
- 它可以用来分析本地Java进程和远程进程。如果要分析远程进程,远程Java程序在运行时需要开启外网权限、开放接口、提供授权认证信息。
- JConsole提供了丰富的功能,如程序概况、内存监控(可以强制应用程序执行Full GC)、线程监控(可以自动检测死锁并显示详细信息)等。
- VisualVM
- VisualVM是一款免费的,集成了多个JDK命令行工具的可视化工具,它基于NetBeans开发,专为开发和生产环境设计。
- VisualVM提供了强大的分析能力,可以对Java应用程序进行性能分析和调优。
- 该工具可以显示虚拟机进程以及进程的配置、环境信息,监视应用程序的CPU、GC(垃圾收集)、堆、方法区以及线程的信息,还可以进行堆转储快照的分析。
- VisualVM还可以进行方法级的程序运行性能分析,帮助开发者找到被调用最多、运行时间最长的方法。
- 它还支持离线程序快照功能,可以收集程序的运行时配置、线程dump、内存dump等信息,并创建一个快照,这个快照可以发送给开发者进行Bug反馈。