JVM-调试排错-汇总
JVM调优参数
常见参数
- -Xms 堆最小值
- -Xmx 堆最大堆值。-Xms与-Xmx 的单位默认字节都是以k、m做单位的。
- -Xmn 新生代大小
- -Xss 设置每个线程可使用的内存大小,即栈的大小。
在相同物理内存下,减小这个值能生成更多的线程,但操作系统对一个进程内的线程数还是有限制的,不能无限生成。
线程栈的大小是个双刃剑,如果设置过小,可能会出现栈溢出,特别是在该线程内有递归、大的循环时出现溢出的可能性更大;如果该值设置过大,就有影响到创建栈的数量,如果是多线程的应用,就会出现内存溢出的错误。 - -XX:NewRatio
- -XX:PermSize
- -XX:MaxPermSize
- -XX:MaxTenuringThreshold
- -XX:SurvivorRatio
- -XX:+UseFastAccessorMethods
- -XX:+AggressiveOpts
- -XX:PretenureSizeThreshold 对象超过多大值时直接在老年代中分配
经验:
Xmn
用于设置新生代的大小。过小会增加Minor GC频率,过大会减小老年代的大小。一般设为整个堆空间的1/4或1/3。XX:SurvivorRatio
用于设置新生代中survivor空间(from/to)和eden空间的大小比例;XX:TargetSurvivorRatio
表示,当经历Minor GC后,survivor空间占有量(百分比)超过它的时候,就会压缩进入老年代(当然,如果survivor空间不够,则直接进入老年代)。默认值为50%。- 为了性能考虑,一开始尽量将新生代对象留在新生代,避免新生的大对象直接进入老年代。因为新生对象大部分都是短期的,这就造成了老年代的内存浪费,并且回收代价也高(Full GC发生在老年代和方法区Perm)。
- 当
Xms=Xmx
,可以使得堆相对稳定,避免不停震荡 - 一般来说,MaxPermSize设为64MB可以满足绝大多数的应用了。若依然出现方法区溢出,则可以设为128MB。若128MB还不能满足需求,那么就应该考虑程序优化了,减少动态类的产生。
垃圾回收
GC考虑的指标
- 吞吐量: 应用耗时和实际耗时的比值;
- 停顿时间: 垃圾回收的时候,由于Stop the World,应用程序的所有线程会挂起,造成应用停顿。
吞吐量和停顿时间是互斥的。
对于后端服务(比如后台计算任务),吞吐量优先考虑(并行垃圾回收);
对于前端应用,RT响应时间优先考虑,减少垃圾收集时的停顿时间,适用场景是Web系统(并发垃圾回收)
垃圾收集器的JVM参数
问题排查 - Linux命令
https://www.pdai.tech/md/java/jvm/java-jvm-debug-tools-linux.html
问题排查 - 工具
入门
jstack
jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。
1 | 基本 |
jmap
命令jmap是一个多功能的命令。它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。
1 | 查看堆的情况 |
jps
jps是jdk提供的一个查看当前java进程的小工具, 可以看做是JavaVirtual Machine Process Status Tool的缩写。
1 | jps # 显示进程的ID 和 类的名称 |
java程序在启动以后,会在java.io.tmpdir指定的目录下,就是临时文件夹里,生成一个类似于hsperfdata_User的文件夹,这个文件夹里(在Linux中为/tmp/hsperfdata_{userName}/),有几个文件,名字就是java进程的pid,因此列出当前运行的java进程,只是把这个目录里的文件名列一下而已。 至于系统的参数什么,就可以解析这几个文件获得。
jinfo
jinfo 是 JDK 自带的命令,可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息
1 | 输出当前 jvm 进程的全部参数和系统属性 |
jstat
jstat参数众多,但是使用一个就够了
1 | jstat -gcutil 2815 1000 |