一、jvm相关参数
1、通过 jstat -gc pid interval 查看每次 GC 之后,具体每一个分区的内存使用率变化情况
2、通过jcmd pid VM.flags 就可以查看到jvm相关的设置参数
3、通过“jmap -heap 进程id”查询出 当前进程的JVM 的配置信息,其中就包括垃圾收集器的设置类型
4、查看 & 分析 GC 日志
首先,我们需要通过 JVM 参数预先设置 GC 日志,通常有以下几种 JVM 参数设置:
-XX:+PrintGC 输出 GC 日志
-XX:+PrintGCDetails 输出 GC 的详细日志
-XX:+PrintGCTimeStamps 输出 GC 的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出 GC 的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行 GC 的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径
eg:-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/log/heapTest.log
如果GC日志非常大,可以用GCViewer工具打开日志文件,图形化界面查看整体的 GC 性能,如下图所示:
也可以用GCeasy工具,并且还可以将日志文件压缩之后,上传到 GCeasy 官网即可看到非常清楚的 GC 日志分析结果
5、堆中年轻代和老年代的比例设置
在 JDK中,默认情况下年轻代和老年代的比例是 1:2,我们可以通过–XX:NewRatio 重置该配置项。
6、堆中年轻代的 Eden 和 To Survivor、From Survivor 的比例是设置
在 JDK中,默认情况堆中年轻代的 Eden 和 To Survivor、From Survivor 的比例是8:1:1,我们可以通过 -XX:SurvivorRatio 重置该配置项。
eg:-XX:SurvivorRatio=8 将 Eden、Survivor 的比例设置为 8:2
7、 -XX:+UseAdaptiveSizePolicy 配置项,JVM 将会动态调整 Java 堆中各个区域的大小以及进入老年代的年龄
ps1、通过 -XX:-UseAdaptiveSizePolicy 关闭该项配置
ps2、如果开启了 -XX:+UseAdaptiveSizePolicy 配置项,–XX:NewRatio 和 -XX:SurvivorRatio 将会失效,而 JDK1.8 是默认开启 -XX:+UseAdaptiveSizePolicy 的。
ps3、在 JDK1.8 中,不要随便关闭 UseAdaptiveSizePolicy 配置项,除非你已经对初始化堆内存 / 最大堆内存、年轻代 / 老年代以及 Eden 区 /Survivor 区有非常明确的规划了。否则 JVM 将会分配最小堆内存,年轻代和老年代按照默认比例 1:2 进行分配,年轻代中的 Eden 和 Survivor 则按照默认比例 8:2 进行分配。这个内存分配未必是应用服务的最佳配置,因此可能会给应用服务带来严重的性能问题。
8、调整某一个程序的堆内存空间
java -jar -Xms4g -Xmx4g heapTest-0.0.1-SNAPSHOT.jar
9、-XX:PetenureSizeThreshold
如果分配的对象内存超过了设置的阀值,会直接分配到老年代,这样做的好处就是可以减少新生代的垃圾回收。
二、java内存/性能调优常用工具、方法、命令
1、linux之top命令
实时显示正在执行进程的 CPU 使用率、内存使用率以及系统负载等信息
2、linux之top Hp pid命令
查看具体线程使用系统资源情况
3、Linux 之 vmstat 命令
vmstat 是一款指定采样周期和次数的功能性监测工具,我们可以看到,它不仅可以统计内存的使用情况,还可以观测到 CPU 的使用率、swap 的使用情况。但 vmstat 一般很少用来查看内存的使用情况,而是经常被用来观察进程的上下文切换。
r:等待运行的进程数; b:处于非中断睡眠状态的进程数; swpd:虚拟内存使用情况; free:空闲的内存;buff:用来作为缓冲的内存数;si:从磁盘交换到内存的交换页数量;so:从内存交换到磁盘的交换页数量;bi:发送到块设备的块数;bo:从块设备接收到的块数;in:每秒中断数;cs:每秒上下文切换次数;us:用户 CPU 使用时间;sy:内核 CPU 系统使用时间;id:空闲时间;wa:等待 I/O 时间;st:运行虚拟机窃取的时间。
4、linux之pidstat命令
pidstat是 Sysstat 中的一个组件;可以通过yum install sysstat 安装该监控组件。pidstat 命令则是深入到线程级别的监测工具。
pidstat的常用参数:
-u:默认的参数,显示各个进程的 cpu 使用情况;-r:显示各个进程的内存使用情况;-d:显示各个进程的 I/O 使用情况;-w:显示每个进程的上下文切换情况;-p:指定进程号;-t:持续显示进程中线程的检测信息。
如:
-r 表示监控内存的使用情况,1 表示每秒的意思,3 则表示采样次数
Minflt/s:任务每秒发生的次要错误,不需要从磁盘中加载页;Majflt/s:任务每秒发生的主要错误,需要从磁盘中加载页;VSZ:虚拟地址大小,虚拟内存使用 KB;RSS:常驻集合大小,非交换区内存使用 KB。
5、JDK 工具之 jstat 命令
jstat 可以监测 Java 应用程序的实时运行情况,包括堆内存信息以及垃圾回收信息
jstat的常用参数:
-class:显示 ClassLoad 的相关信息;-compiler:显示 JIT 编译的相关信息;-gc:显示和 gc 相关的堆信息;-gccapacity:显示各个代的容量以及使用情况;-gcmetacapacity:显示 Metaspace 的大小;-gcnew:显示新生代信息;-gcnewcapacity:显示新生代大小和使用情况;-gcold:显示老年代和永久代的信息;-gcoldcapacity :显示老年代的大小;-gcutil:显示垃圾收集信息;-gccause:显示垃圾回收的相关信息(通 -gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;-printcompilation:输出 JIT 编译的方法信息。
如:
S0C:年轻代中 To Survivor 的容量(单位 KB);S1C:年轻代中 From Survivor 的容量(单位 KB);S0U:年轻代中 To Survivor 目前已使用空间(单位 KB);S1U:年轻代中 From Survivor 目前已使用空间(单位 KB);EC:年轻代中 Eden 的容量(单位 KB);EU:年轻代中 Eden 目前已使用空间(单位 KB);OC:Old 代的容量(单位 KB);OU:Old 代目前已使用空间(单位 KB);MC:Metaspace 的容量(单位 KB);MU:Metaspace 目前已使用空间(单位 KB);YGC:从应用程序启动到采样时年轻代中 gc 次数;YGCT:从应用程序启动到采样时年轻代中 gc 所用时间 (s);FGC:从应用程序启动到采样时 old 代(全 gc)gc 次数;FGCT:从应用程序启动到采样时 old 代(全 gc)gc 所用时间 (s);GCT:从应用程序启动到采样时 gc 用的总时间 (s)。
6、JDK 工具之 jstack 命令
一种线程堆栈分析工具,最常用的功能就是使用 jstack pid 命令查看线程的堆栈信息,通常会结合 top -Hp pid 或 pidstat -p pid -t 一起查看具体线程的状态,也经常用来排查一些死锁的异常
7、JDK 工具之 jmap 命令
jmap 除了可以查看堆内存初始化配置信息以及堆内存的使用情况。还可以使用 jmap 输出堆内存中的对象信息,包括产生了哪些对象,对象数量多少等。
如:
7.1、可以用 jmap 来查看堆内存初始化配置信息以及堆内存的使用情况
7.2、使用 jmap -histo[:live] pid 查看堆内存中的对象数目、大小统计直方图,如果带上 live 则只统计活对象:
7.3、可以通过 jmap 命令把堆内存的使用情况 dump 到文件中
ps1、一般使用方式如下:
java -jar -Xms1000m -Xmx4000m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/tmp/heapTest.log heapTest-0.0.1-SNAPSHOT.jar
ps2、可以使用 MAT 工具打开文件进行分析
看到具体哪个对象引用了这个Byte数组对象