JVM学习-- JVM调优

梦里梦外; 2024-04-01 18:08 210阅读 0赞

一、选择垃圾收集器

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

一般情况,

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和内存的占用都比较高

38cea9ae24e0488188ccb2e3f28ef2b3.png

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 ,一定要找到是哪个线程持有这把锁

怎么找?搜索jstack dump的信息,找 ,看哪个线程持有这把锁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

程序启动参数:

  1. 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占用很高的进程号

  1. top

703159691b0748e58ba25b3df6de28a6.png

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

  1. top -Hp 56959

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

e6698b5968924f0d9908611ee10e517a.png

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

  1. printf "%x\n" 56960

e193bbf24bb243889db4ce49dfe8e948.png

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

  1. jstack 56959 | grep de80 -A 30

7426a824728d43ab97d909b9460eef69.png

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

d1484df1f4334bc6a388cf31ca2f7d35.png

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

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

1) 导出堆转储文件

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

  1. -XX:+HeapDumpOnOutOfMemoryError

2)分析

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

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

4a47ccbb390244938868939d5bd9da33.png

发表评论

表情:
评论列表 (有 0 条评论,210人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JVM-JVM性能

    JVM性能调优的目标和方法 JVM性能调优的目标是使JVM在运行Java应用程序时能够更加高效地利用计算机的资源,以提高应用程序的性能和响应能力。具体来说,JVM性能调优

    相关 JVM

    一、JVM调优的监控方法 jvm在对进行问题排查,线程等关注问题,在理解jvm的内存分配和垃圾回收,java类的编译和加载等等理论知识的前提下要学会使用工具去观察jvm中的实

    相关 JVM

    1. 年轻代大小选择 (1) 响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到

    相关 JVM

    前提: 某大型跨境电商业务发展非常快,线上机器扩容也很频繁,但是对于线上机器的运行情况,特别是jvm内存的情况,一直没有一个统一的标准来给到各个应用服务的owner。经过6

    相关 JVM

    年轻代大小选择 响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对

    相关 JVM

    JVM调优是所有初级程序员向高级迈入的必经之路,而这个过程又需要许多JVM内存知识。下面就总结一二,和大家分享一下: 1.JVM内存模型 JVM内存模型如下图所示: