JVM调优-核心-常用命令和工具-服务问题-常见题分析

7 篇文章 0 订阅
5 篇文章 0 订阅

----------------案例---------------

JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙! https://mp.weixin.qq.com/s/Sk_P1tH0WFXIys67Eep0zg

------------调优工具--------------


1)jvisualvm(装visualGC+jconsole)

 jvisualvm 一个基于图形化界面的、可以查看本地及远程的JAVA GUI监控工具

dk自带全能工具,分析程序死锁,(监视标签里还能导出正在监控的)内存dump、线程dump;(用它的VisualGc插件来)监控内存变化、GC变化等。还能导入生产的堆dump文件==堆快照内容(dump文件里能看到类实例对象的大小占比找出大对象)

2)jconsole

 jconsole 一个java GUI监视工具,可以以图表化的形式显示各种数据
对JVM中内存,线程和类等的监控

3)GCeasy

一款专业分析gc日志的工具,能查内存大小分配比例,吞吐量,最大最小停顿时间,普通GC和fullGC的GC耗时时长和,查找内存泄漏

 
 4)其他
 程序运行中经常会遇到各种问题,定位问题时通常需要综合各种信息,如系统日志、堆dump文件、线程dump文件、GC日志等。通过虚拟机监控和诊断工具可以帮忙我们快速获取、分析需要的数据,进而提高问题解决速度。 本文将介绍虚拟机常用监控和问题诊断命令工具的使用方法,主要包含以下工具:
   jps 显示系统中所有Hotspot虚拟机进程
   jstack 显示虚拟机的线程栈快照信息
   jstat收集Hotspot虚拟机各方面运行数据(堆实时内存情况--大对象占比,GC回收)
   jmap用于生成虚拟机的内存快照信息(堆快照)
   jinfo 显示虚拟机的配置信息(看内存各块配置大小,看GC收集器的配置)
   jhat 用于对JAVA heap进行离线分析的工具(和jvisualvm类似)

   Jdb 对core文件和正在运行的Java进程进行实时地调试

------------21.调优命令------按顺序来查未知问题--------

1)------- top -c    // 通过查看该进程,再直接输一个大写P,会按CPU百分比倒序,找到最占cpu的进程ID1=11146
1)-------top -Hp 11146  // 可以查看该进程下各个线程的cpu使用情况,看看是否哪个线程问题明显
1)-------jinfo -flags 11146 // 查看jvm当前配置的参数,判断堆里的新老年代分配比例合理不。??
1)------- jstat -class 11146 // 命令可以查看堆内存加载类的数量,class可以换成其他变量,比如查gc次数、新老代垃圾回收统计

1)-------jmap下的一些命令    // 用于生成heap dump文件==堆快照内容,Java Virtual Machine Memory Map 
1)------- jstack下的一些命令     // jstack,用于生成java虚拟机当前时刻的线程快照==堆dump文件里的内容。查找死锁

jps,JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。
jstat,JVM statistics Monitoring是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

jhat,JVM Heap Analysis Tool命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看

df -lh //磁盘占比查看
jps -mlvv  //(Java Virtual Machine Process Status Tool)
jps -mlvv  //找出当前java进程号,,然后显示出内存分配及GC器配置信息、依赖jar包路径全称
ps -ef | grep java | grep pcs-core  //找出所有目录的java进程号,并过滤一下带pcs-core名称的进程号,然后显示出内存分配及GC器配置信息、依赖jar包路径全称
jps -v  //输出传递给JVM的参数

----------------------排查oom顺序---------------------

        总结
1.如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。(分析原因)
2.要制作堆Dump可以直接使用jvm自带的jmap命令
3.可以先使用jmap -heap命令查看堆的使用情况,看一下各个堆空间的占比情况。
4.使用jmap -histo:[live]查看当前堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。
5.也可以使用 jmap -dump:format=b,file=<fileName>命令将堆信息保存到一个文件中,再借助jhat命令或jvisualvm查看详细内容
6.在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,做对比,把内存文件进行编号归档,便于后续内存整理分析。

7.在用cms gc的情况下,执行jmap -heap有些时候会导致进程变T,因此强烈建议别执行这个命令,如果想获取内存目前每个区域的使用状况,可通过jstat -gc(实时查看)或jstat -gccapacity来拿到。

------------------死锁查找有哪些方面法-----------------

一、让运维生成线程快照,用jvisualvm分析程序死锁
二、用jstack工具和jvm自身支持的命令,直接命令行查出来:

jstack找出占用cpu最高的堆栈信息
1,使用命令top -p <pid> ,显示你的java进程的内存情况,pid是你的java进程号,比如4977
2,按H,获取每个线程的内存情况 
3,找到内存和cpu占用最高的线程tid,比如4977 
4,转为十六进制得到 0x1371 ,此为线程id的十六进制表示
5,执行 jstack 4977|grep -A 10 1371,得到线程堆栈信息中1371这个线程所在行的后面10行 
6,查看对应的堆栈信息找出可能存在问题的代码

------------------GC调优步骤------通过gc日志的方法------------

打印GC日志
-XX:+PrintGCDetails  -XX:+PrintGCTimeStamps  -XX:+PrintGCDateStamps  -Xloggc:./gc.log
Tomcat则直接加在JAVA_OPTS变量里
分析日志得到关键性指标
分析GC原因,调优JVM参数
1、Parallel Scavenge收集器(默认)
分析parallel-gc.log
调优:
第一次调优,设置Metaspace大小:增大元空间大小-XX:MetaspaceSize=64M  -XX:MaxMetaspaceSize=64M
第二次调优,增大年轻代动态扩容增量,默认是20(%),可以减少young gc:-XX:YoungGenerationSizeIncrement=30
比较下几次调优效果:
吞吐量             最大停顿      平均停顿    Young gc     Full gc
98.356%     120 ms   19 ms        19        2
 99.252%     20 ms        10 ms        16        0
99.24%                        17

2、配置CMS收集器
 -XX:+UseConcMarkSweepGC
分析cms-gc.log
3、配置G1收集器
-XX:+UseG1GC
分析g1-gc.log 
young GC:[GC pause (G1 Evacuation Pause) (young)
initial-mark:[GC pause (Metadata GC Threshold) (young) (initial-mark)   (参数:InitiatingHeapOccupancyPercent)
mixed GC:[GC pause (G1 Evacuation Pause) (mixed)                (参数:G1HeapWastePercent)
full GC:[Full GC (Allocation Failure)                                (无可用region)
(G1内部,前面提到的混合GC是非常重要的释放内存机制,它避免了G1出现Region没有可用的情况,否则就会触发Full GC事件。
CMS、Parallel、Serial GC都需要通过Full GC去压缩老年代并在这个过程中扫描整个老年代。G1的Full GC算法和Serial GC收集器完全一致。当一个Full GC发生时,整个Java堆执行一个完整的压缩,这样确保了最大的空余内存可用。G1的Full GC是一个单线程,它可能引起一个长时间的停顿时间,G1的设计目标是减少Full GC,满足应用性能目标。)
查看发生MixedGC的阈值:jinfo -flag InitiatingHeapOccupancyPercent 进程id
调优:
第一次调优,设置Metaspace大小:增大元空间大小-XX:MetaspaceSize=64M  -XX:MaxMetaspaceSize=64M
第二次调优,添加吞吐量和停顿时间参数:-XX:GCTimeRatio=80  -XX:MaxGCPauseMillis=100   

分析工具:gceasy,GCViewer 
 

--------------------------常见题分析--------------------------

08-JVM整体结构与垃圾回收算法介绍

1、(K73)(a+b)*10,10是存在哪里的?是常量池么?,如果是常量池,在进行运算的时候,是通过指针来找到的吧,这样咱们的架构图是不是少了一部分啊?
10是在常量池,因为常量池在jdk1.8以后已经移到元空间了,所以画运行时数据区不好一起画出来,PPT上有关于常量池的存储变化
2、(L81)
动态链接 和 引用 有什么区别?
动态链接指对类信息的引用在运行过程中才能确定,引用是指对象级别,一个类信息级别,一个队对象级别,动态链接要彻底理解还需要了解下编译原理等知识,可查下相关资料
3、(F43)堆到底装对象的什么部分(只是对象的引用吗?)?方法区里放的是对象的字节码,栈里放的是线程所有方法执行的代码,感觉堆里没有什么东西放了啊?
对象里的数据哈,成员变量之类的啊,栈里放到是方法的局部变量
4、在服务器里,我们是怎么启动jvm的(一般我们就安装jdk包,配置了一下)
最终还是通过java命令哈,服务器启动也是通过java命令运行jar包里的一个入口类启动
5、tomcat我们安装时,压根就没有配置jdk的路径,是怎么和jdk关联上的(也就是tomcat里的东西怎么,什么时候放到jvm中去的?)
需要配置JAVA_HOME的,你不配置试试能启动不,tomcat启动时会去环境变量里找JAVA_HOME
 

09-类加载器深入解析

1、(M12)双亲委派机制能够保证核心类安全,那其他的非核心类呢?
你公司自己开发的类没办法保证,JVM只保证它自己的核心类不被破坏
2、(F43)怎么把jstack查出的线程单独杀掉(一般根据nid找出的pid杀掉会连带杀掉进程)?
你这找出的pid是进程id吧,还真没单独kill过某一个线程。。貌似有点困难
3、(K73)内存泄漏通过什么命令来查呢?
还是要用jmap的内存快照分析

10-GC日志格式详解

1、(M49)实际生产OOM处理处理思路是什么?
答:先重启让程序运行,然后根据溢出生成的dump文件分析原因,解决可能存在的bug
2、(H36) java四种引用类型跟垃圾回收的关系,平时只用考虑强引用吗?
答:我们这里说的引用都是指的强引用,其他几种引用用得不多吧
3、(C81)我们用的 parallel gc, 在服务器没有用户访问的时候,堆内存会慢慢增长,直到内存使用率达到95%以上甚至到了99%,触发了full fc才会降下来,然后继续慢慢增长,如此循环。而有用户请求时反而不会有这种情况,内存增长的速度稍快一些,但会频繁回收。
答:把dump拿出来分析下看是什么对象一直在增长,然后找对应的代码分析
4、问题:对象多大字节会放H区
L50
答:超过region块一半以上空间的对象有可能会被放入H区
5、java堆内存的模型,是在启动jvm参数 设置哪个垃圾回收器定的么?老师讲到G1垃圾回收器的时候讲到说 java堆不是 
 不要考虑 yong 区 eden  from  to  的概念了,根据这个理念我觉得应该是所以确认一下。
I41
答:是启动的时候指定垃圾回收器,不指定的话JDK会根据版本默认一个回收器
是说不在想其它收集器那样考虑young和old区了,但是每个region还是有区别的,仔细看下我视频里讲的region分类
6、cms是1.8默认老年代的收集器,parallel是1.8默认新生代的收集器对吗?各个版本的jdk中新老年代,默认收集器,从1.6开始。
I66
答:我课上说了jdk1.8默认的是parallel收集器,它还有一个老年代版本,年轻代和老年代默认都是用parallel。Jdk9是G1,jdk1.8前版本默认收集器自己去查下文档吧

--11-GC调优实战--


1、(M72)
   线上单机再跑的,那是需要重启启动,配上参数,来打印日志呀?
重启配置上可以,如果不想重启通过jinfo应该也是可以动态修改一些jvm参数的,可以查下相关资料
2、 线上再跑的项目如果需要调整元空间大小,也需要重新启动项目吗?
可以看下jinfo这个命令,可以动态修改一些jvm参数的,不确定是否一定能修改元空间大小,可以查下相关资料
3、(B27)
 GC调优,不应该是直接根据启动日志就能做到调优吧?我觉得更多的是根据系统长时间运行,得到的JVM的GC日志,才能有一个JVM GC整体的概况,才能更好做到调优。
是的,要根据长时间的运行日志来分析,我课上只是拿启动日志举例
4、(M51)
   gc频繁和gc时间长  这两种调优的基本思路是什么?
gc频繁可能是分配的空间较少,可以结合日志分析看是否需要调大一点,我最后一节课上有讲
gc时间长就需要结合日志具体分析了,不好说具体原因,有可能是内存分配过大,或者程序有bug导致垃圾对象过多
5、jvm堆的结构是不是由收集器决定的 ?例如g1 就会跟成多个regin区域管理。
是的,就是JVM内部根据不同的收集器的不同实现

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java_爱吃肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值