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

    怎么找?搜索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

    程序启动参数:

    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),再看看是否有代码问题

     

  • 相关阅读:
    二 TypeScript 基础(初识和语法)
    pytest-yaml 测试平台-1.新增项目和用例(有平台体验地址)
    如何比较两个对象以确定第一个对象包含与JavaScript中的第二个对象等效的属性值?
    CDA Level1——1.数据分析的基本概念
    让你的聊天气泡丰富多彩
    【Ubuntu】命令行快速移动光标
    从零开始写 Docker(十)---实现 mydocker logs 查看容器日志
    远程办公或常态化,“小城房”or“大城床”你会怎么选?
    kafka集群配置
    [RPC] Motan快速开始
  • 原文地址:https://blog.csdn.net/CelineT/article/details/127832952