JVM学习-- JVM调优

一、选择垃圾收集器

垃圾收集器和内存大小有关

一般情况,

serial+serial old 适用几十兆内存

ps+po 适用几百兆~几个G

parNew+CMS 可以用到20G

G1 可以用到上百G

ZGC 可以 4T~16T

1.  常见垃圾收集器组合参数设定

-XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old

-XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认) 【PS + SerialOld】

-XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old

-XX:+UseG1GC = G1

jvm命令行参数:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

二、规划

1. 调优要根据具体的业务场景,不要抛开业务场景

2. 调优需要有监控,根据压测结果,查看具体的结果

三、解决方案

1. top命令

查看当前cpu和内存占用较高的进程

例如,下图中pid为1364的进程cpu和内存的占用都比较高

2. top -Hp pid

观察进程中的线程,哪个线程CPU和内存占比高

top -Hp查看的是10进制的线程号

3. jps

定位具体java进程

4. jstack pid

把该进程的每个线程都列出来(线程状态、nid)

重点关注:WAITING BLOCKED(waiting on <0x0000000088ca3310> (a java.lang.Object) )

如果有一个进程中有很多线程都在waiting on <xx> ,一定要找到是哪个线程持有这把锁

怎么找?搜索jstack dump的信息,找<xx> ,看哪个线程持有这把锁RUNNABLE

其中nid就是16进制的线程号,与top -Hp的线程号对应

5. jinfo pid

查询线程的具体信息

6. jstat -gc 

打印垃圾回收信息,后面可以加一个时间参数(毫秒),间隔时间打印垃圾回收信息

7. jmap

jmap -histo pid | head -20:查看内存占用的前20个类

jmap -dump:format=b,file=xxx pid/jmap -histo:手动导出堆转储文件(对系统影响较大)

1) 可以在启动程序的时候设定启动参数:-XX: +HeapDumpOnOutOfMemoryError,这样oom的时候,会自动产生堆转储文件

2)做了服务器的高可用(备份),停掉一台服务器,没有影响

8. 分析dump文件

使用MAT / jhat /jvisualvm 进行dump文件分析

jhat用法: java命令--jhat命令使用 - 白灰 - 博客园

9. jconsole

图形化界面,需要在服务器打开JMX

程序启动参数:

java -Djava.rmi.server.hostname=192.168.17.11 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=11111 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false XXX

windows上打开 jconsole远程连接

10.jvisualVm

和jconsole差不多,都是图形化的界面,但是比jconsole更好用一点

 

四、在线排查工具arths

1. 背景

在生产上我们经常会碰到一些不好排查的问题,例如线程安全问题,用最简单的threaddump或者heapdump不好查到问题原因。为了排查这些问题,有时我们会临时加一些日志,比如在一些关键的函数里打印出入参,然后重新打包发布,如果打了日志还是没找到问题,继续加日志,重新打包发布。对于上线流程复杂而且审核比较严的公司,从改代码到上线需要层层的流转,会大大影响问题排查的进度。

2. jvm命令观察jvm信息

3. thread定位线程问题

4. dashboard 观察系统情况

5. heapdump + jhat分析

6. jad反编译

动态代理生成类的问题定位

第三方的类(观察代码)

版本问题(确定自己最新提交的版本是不是被使用)

7. redefine 热替换

五、实战

1.  系统CPU经常100%,如何调优?

CPU100%那么一定有线程在占用系统资源

 1)找出哪个进程cpu高

top命令,查找cpu占用很高的进程号

top

  2)该进程中的哪个线程cpu高(top -Hp)

top -Hp 56959

查看该进程下哪个线程cpu占用高

 3)把刚刚的线程号转成16进制

printf "%x\n" 56960

 

 4)导出该线程的堆栈 (jstack)

jstack 56959 | grep de80 -A 30

此时,可以看到,JvmTest的第8行有问题

 

 果然,这个地方有个死循环

2. 系统内存飙高,如何查找问题?(OOM)

1) 导出堆转储文件

可以通过加启动参数,这样出现OOM的时候,会自动导出堆转储文件hprof

-XX:+HeapDumpOnOutOfMemoryError

2)分析

可以通过jvisualVm分析堆转储文件

判断是内存泄漏还是内存溢出,
如果是内存泄漏,找到GC Roots引用链,定位到对象创建的位置,找到产生内存泄漏的代码位置
如果是内存溢出,看看能否调大堆参数(Xms Xmx),再看看是否有代码问题

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值