文章目录
- 前言
- 一、了解JVM常用命令行参数
- 1、命令行参数概述
- 2、常用命令
- 3、通过案例学命令行参数(Linux)
- 4、区分概念
- 二、GC日志详解
- 1、打印详细日志
- 2、日志描述
- 3、解析案例
- 三、调优前的基础概念
- 四、调优是什么?
- 五、调优1:JVM规划和预调优
- 1、涨知识时刻
- 2、概述
- 3、案例1:垂直电商,最高每日百万订单,处理订单系统需要什么样的服务器配置?
- 4、案例2:12306遭遇春节大规模抢票应该如何支撑?
- 六、调优2:优化JVM运行环境(慢、卡顿)
- 1、三个问题
- 2、问题1:扩展了硬件,为什么更慢了
- 3、问题2:系统CPU经常100%,如何调优?(面试高频、美团问过)
- 4、问题3:系统内存飙高,如何查找问题?(面试高频)
- 5、如何监控JVM?
- 七、调优3:解决JVM运行出现的各种问题*
- 1、风险评控-测试
- a、案例-代码
- b、定位线程占用CPU高的案例*
- i、项目启动命令1
- ii、top命令:找到高内存的进程号(pid)。
- iii、jstack:定位具体的线程
- iv、jps命令:打印java 的相关进程
- v、阿里规范:线程名要有意义
- vi、jinfo:进程的虚拟机详细信息
- vii、jstat命令:动态观察gc情况
- viii、jmap命令:查找有多少对象产生
- ix、项目启动命令2(新增HeapDump参数)
- x、dump文件分析:jhat /jvisualvm/MAT
- c、作业:1:写一个死锁程序,用jstack观察 2 :写一个程序,一个线程持有锁不释放,其他线程等待
- 2、jconsole远程连接(图形监控)
- 3、jvisualvm远程连接(了解即可)
- 4、jprofiler (收费)
- 5、阿里的arthas在线排查工具
- a、描述
- b、为什么需要在线排查?
- c、jvm命令:观察jvm信息
- d、thread命令:定位线程问题
- e、dashboard命令:实时观察系统情况
- f、heapdump命令:等价于 jmap 命令
- g、jhat(JDK自带)命令:分析 dump文件
- h、jad命令:反编译
- i、redefine命令:热替换
- i、案例测试-目的
- ii、代码
- iii、启动Arthas ,监控TT小程序
- iv、重新修改、编译T.java
- v、redefine热编译
- vi、结果执行
- j、sc命令:查看 JVM 已加载的类信息
- k、watch 命令:函数执行数据观测
前言
- 本博客主要讲了:
- JVM常用命令行参数
- GC日志的详解
- 调优三大层面的细节
一、了解JVM常用命令行参数
JVM调优第一步,了解JVM常用命令行参数
1、命令行参数概述
- JVM的命令行参数参考(只有8版本):https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
- HotSpot参数分类
标准: - 开头,所有的HotSpot都支持
非标准:-X 开头,特定版本HotSpot支持特定命令
不稳定:-XX 开头,下个版本可能取消
2、常用命令
- :查看java 的版本
- :查看java 非标准的、特定HotSpot的特定命令
- 。(Linux过滤查找)
- :查看jvm默认参数
- 是打印所有的默认参数设置
- 是打印最终值,如果某个默认值被新值覆盖,显示新值
- 是打印命令行参数。
3、通过案例学命令行参数(Linux)
- :查看JVM详细信息
- = ParNew + CMS + Serial Old
- :最终参数值
- :
- : HelloGC是测试类
- :n是new,新生代的大小
- :设置 heap 初始化大小
- :设置 heap 最大值 (与初始值一般设置同大小值)
- :打印命令行参数
- :打印GC回收信息
- 其他几个详细信息
- :GC详细信息
- :GC时间
- :GC原因
8.
9. 默认参数值
10. 最终参数值
11. 找到对应的参数
* :找与GC相关的命令行参数
4、区分概念
内存泄漏memory leak,内存溢出out of memory
- 问题:
- 1)有对象应该是要被标记成垃圾回收的,但是因为还有引用指向该对象,从而该对象一直没被清除,实际已经没有代码块要使用了。存在这种对象时就可以说是内存泄漏了嘛?
- 2)同时是不是内存泄漏的对象一多了之后,就会产生内存溢出的问题?
- 3)如果一个对象new的时候,就比堆内存老年代都要大,是不是就直接报内存溢出?
- 解释:
- 在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
二、GC日志详解
1、打印详细日志
2、日志描述
- 命令 ,如下所示
- 意思就是 time 命令执行的情况 在 态、态、(总)态,各占用多长时间。
3、解析案例
heap dump信息解刨如下:
三、调优前的基础概念
- 两个概念
- :用户代码时间 /(用户代码执行时间 + 垃圾回收时间)
- : 越短,响应时间越好
- 所谓调优,首先确定,追求啥?还是在满足一定的响应时间的情况下,要求达到多大的吞吐量
- 问题:
- 如果是科学计算:吞吐量 优先。
- 如果是数据挖掘,thrput(吞吐量)优先。
- 吞吐量优先
- 一般选:(PS + PO)版本
- 响应时间优先(网站类型)
- 一般选 GUI API (1.8版本选择 G1)
四、调优是什么?
- 根据需求进行
- 优化运行JVM运行环境(慢,卡顿)
- 解决JVM运行过程中出现的各种问题(OOM是其中一部分)
从下面三个章节开始细讲:
五、调优1:JVM规划和预调优
1、涨知识时刻
2、概述
- 调优,从业务场景开始,没有业务场景的调优都是耍流氓
- 无监控(压力测试,能看到结果),不调优
- 步骤:
- 熟悉业务场景(没有最好的垃圾回收器,只有最合适的垃圾回收器)(以下两个更看重哪个)
- 响应时间、停顿时间 [CMS G1 ZGC] (需要给用户作响应)
- 吞吐量 = 用户时间 /( 用户时间 + GC时间) [PS]
- 选择回收器组合
- 计算内存需求(经验值 1.5G 16G)
- 选定CPU(越高越好)
- 设定年代大小、升级年龄
- 设定日志参数
- 生产环境产出的日志参数:
- 指定文件名和路径
- :GC文件循环使用
- :GC日志文件为5个
- :每个GC文件大小为20M
- :打印GC详细信息
- :GC时间戳
- :GC原因
- 一共五个日志文件,每个20M,共100M。
- 或者每天产生一个日志文件(不可以的,每天的日志量太大,不好差)
- 观察日志情况
3、案例1:垂直电商,最高每日百万订单,处理订单系统需要什么样的服务器配置?
- 问:垂直电商,最高每日百万订单,处理订单系统需要什么样的服务器配置?
- 这个问题不太专业,因为垂直电商不可能做到每日百万订单。
- 遇到这种问法时,还是需要去分析。比如考虑高峰访问量,假设一小时产生36w订单,即100订单/秒,高峰就再次假设1000订单/秒。
- 。假设一个订单对象为512k,1000订单总和是500M左右。
- 这样新生代设置500M就可以,当然250M也可以,多回收几次就行。所以此时一般有响应时间要求,即在多少响应时间(比如100ms)内进行设计,然后进行压测。
4、案例2:12306遭遇春节大规模抢票应该如何支撑?
- 问:12306遭遇春节大规模抢票应该如何支撑?
- 12306应该是中国并发量最大的秒杀网站:号称并发量100W最高
一般先从CDN开始,在全国做不同的CDN缓存,接下来是一堆的LVS,接下来就是NGINX,接下来就是Tomcat等服务器。 - Redis可以撑得住单机1w并发。
- 普通电商订单 -> 下单 ->订单系统(IO)减库存 ->等待用户付款
- 此外,架构设计也是和业务逻辑紧密相关的。
- 在商城付款流程中,普通电商订单 -> 下单 ->订单系统(IO)减库存,减库存和订单的生成应该是异步进行的,最后一步是用户付款。
- 在具体的功能模块,比如订单生成,最后还会把压力压到一台服务器,可以做分布式本地库存 + 单独服务器做库存均衡。
- 怎么得到一个事务会消耗多少内存?
- 弄台机器,看能承受多少TPS?是不是达到目标?扩容或调优,让它达到
- 用压测来确定
六、调优2:优化JVM运行环境(慢、卡顿)
1、三个问题
- 有一个50万PV的资料类网站(从磁盘提取文档到内存)原服务器32位,1.5G的堆,用户反馈网站比较缓慢,因此公司决定升级,新的服务器为64位,16G的堆内存,结果用户反馈卡顿十分严重,反而比以前效率更低了。
- 问题:为什么?如何优化?
- 系统CPU经常100%,如何调优?(面试高频)
- 系统内存飙高,如何查找问题?(面试高频)
2、问题1:扩展了硬件,为什么更慢了
有一个50万PV的资料类网站(从磁盘提取文档到内存)原服务器32位,1.5G的堆,用户反馈网站比较缓慢,因此公司决定升级,新的服务器为64位,16G的堆内存,结果用户反馈卡顿十分严重,反而比以前效率更低了。
- 问题:为什么?
- 很多用户浏览数据,很多数据load到内存,内存不足,,。
- 为什么会更卡顿?
- 内存越大,YGC频率变低(好事);因为空间变大,所以STW变长。 时间越长
- 如何优化?
- 改变垃圾回收器:(JDK1.8) 改成 或者
3、问题2:系统CPU经常100%,如何调优?(面试高频、美团问过)
- 系统CPU经常100%,如何调优?(面试高频、美团问过)
- 我之前写过一篇文章,就是解决这个问题的
Java面试题之cpu占用率100%,进行定位和解决 - CPU100%那么一定有线程在占用系统资源,
- 找出哪个进程cpu高()
- 该进程中的哪个线程cpu高()
- 导出该线程的堆栈 ()
- 查找哪个方法(栈帧)消耗时间 ()
- 工作线程占比高 | 垃圾回收线程占比高
4、问题3:系统内存飙高,如何查找问题?(面试高频)
- 系统内存飙高,如何查找问题?(面试高频)
- 导出堆内存 ()
- 分析 ( … )
- (j开头的工具都是JDK自带的)
5、如何监控JVM?
- :收费
- :阿里的
- …
七、调优3:解决JVM运行出现的各种问题*
无监控,不调优
1、风险评控-测试
a、案例-代码
b、定位线程占用CPU高的案例*
i、项目启动命令1
- 在jvm路径下的终端中:
- 一般是运维团队首先受到报警信息(CPU Memory)
ii、top命令:找到高内存的进程号(pid)。
- 命令观察到问题:内存不断增长 CPU占用率居高不下。找到高内存的pid进程号。
Mac:内存占了46.7%,在越来越大。 - :打印进程里的所有线程。观察线程,看哪个线程CPU和内存占比高。正常来说占CPU比较多的是垃圾回收的线程比较多,因为垃圾太多回收不过来了,每次只能回收一点点。
iii、jstack:定位具体的线程
- :查看使用方法。可以定位具体的线程,查看问题。注意:
- :会把都给打印出来。
最开始的线程,这里起了50个线程,所以这里是50开始的,倒序的。
还有一个点,需要看 。 - 最后的线程,中间省略啦。
:处理引用,JVM内部的线程。
:垃圾回收线程。
在往下都是垃圾回收的线程。 - : 定位线程状况,重点关注:WAITING、BLOCKED
eg.
很重要,意思就是:waiting 正在等待这把锁的释放,
:会将进程里的所有线程都给列举出来。
假如有一个进程中100个线程,很多线程都在 ,一定要找到是哪个线程持有这把锁
怎么找? 搜索 的信息,找 ,看哪个线程持有这把锁RUNNABLE
作业:1:写一个死锁程序,用jstack观察 2 :写一个程序,一个线程持有锁不释放,其他线程等待
iv、jps命令:打印java 的相关进程
- :java 的 ps,打印java 的相关。即定位具体java进程。(win、Linux 都行)
v、阿里规范:线程名要有意义
- 为什么阿里规范里规定,线程的名称(尤其是线程池)都要写有意义的名称?
答:创建线程或者线程池时请指定有意义的线程名称,方便出错时回溯。
- 怎么样自定义线程池里的线程名称?
答:(自定义ThreadFactory)
vi、jinfo:进程的虚拟机详细信息
- :打印进程的虚拟机详细信息。
等等。
vii、jstat命令:动态观察gc情况
- :(不好用,可视化不好用)动态观察gc情况 / 阅读GC日志发现频繁GC。好用的工具:(下面一一讲解了)
: 每个500个毫秒打印GC的情况。 - 如果面试官问你是怎么定位OOM问题的?如果你回答用图形界面(错误)
- 已经上线的系统不用图形界面,用什么?(用 cmdline(在远程服务器就可以看)、 arthas(阿里的))
- 图形界面到底用在什么地方?测试!测试的时候进行监控!(压测观察)
viii、jmap命令:查找有多少对象产生
- ,查找有多少对象产生
- :jmap命令:https://www.jianshu.com/p/a4ad53179df3。线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿(电商不适合)
1:设定了参数HeapDump,OOM的时候会自动产生堆转储文件
2:很多服务器备份(高可用),停掉这台服务器对其他服务器不影响
3:在线定位(一般小点儿公司用不到)
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。
ix、项目启动命令2(新增HeapDump参数)
x、dump文件分析:jhat /jvisualvm/MAT
- 使用MAT / jhat /jvisualvm 进行dump文件分析
https://www.cnblogs.com/baihuitestsoftware/articles/6406271.html
- 找到代码的问题
c、作业:1:写一个死锁程序,用jstack观察 2 :写一个程序,一个线程持有锁不释放,其他线程等待
2、jconsole远程连接(图形监控)
Linux没有图形化界面,一般都是win链接Linux;一般远程很少使用图像化界面观察得到, 一般可以使用在线跟踪,阿里的arthas,当然远程监控也有用。
jconsole远程连接时,远程需要开一些服务,JMX(Java Manager Extensions,java管理拓展),就是远程管理、监控一些java进程,需要在服务器上的JMX打开。然后用支持的JMX的工具去连接展示即可
- 程序启动加入参数(开启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 接下来的参数。。。
- 全的参数:
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 java -Xms200M -Xmx200M -XX:+PrintGC com.mashibing.jvm.c5_gc.T15_FullGC_Problem01
- 如果遭遇 Local host name unknown:XXX的错误,修改/etc/hosts文件,把XXX加入进去
- 关闭linux防火墙(实战中应该打开对应端口)
- windows上打开 jconsole远程连接 192.168.17.11:11111
3、jvisualvm远程连接(了解即可)
- mac的路径:
- 我这里以本地具体。页面展示如下:
- 概述:参数等信息
- 监视:CPU、堆、元空间、类、线程等信息。
- 线程
- 抽样器:可以看到类的加载大小情况等,右边有字节和实例个数,可以从这里看出来是哪个类导致的OOM。
- jprofile
4、jprofiler (收费)
5、阿里的arthas在线排查工具
a、描述
- Arthas 官网:https://arthas.aliyun.com/doc/,目前最新版本3.6.7,直接在线上服务监控操作,不用远程挂可视化工具的界面。官网很详细,可以仔细观看
b、为什么需要在线排查?
在生产上我们经常会碰到一些不好排查的问题,例如线程安全问题,用最简单的threaddump或者heapdump不好查到问题原因。为了排查这些问题,有时我们会临时加一些日志,比如在一些关键的函数里打印出入参,然后重新打包发布,如果打了日志还是没找到问题,继续加日志,重新打包发布。对于上线流程复杂而且审核比较严的公司,从改代码到上线需要层层的流转,会大大影响问题排查的进度。
c、jvm命令:观察jvm信息
d、thread命令:定位线程问题
- :定位线程问题
e、dashboard命令:实时观察系统情况
- : 观察系统情况
f、heapdump命令:等价于 jmap 命令
- heapdump 使用:https://arthas.aliyun.com/doc/heapdump.html
- :分析,heapdump等价于 jmap 命令,(能在线定位就不要导出dump文件)。使用 ,查看: ,有时文件太大会导致OOM,通过 jhat查看指定内存的参数,然后使用 ,(jhat是JDK自带的工具;MAT也可以分析dump文件,大多数人使用(下面就是用这个分析的 );还有jvisualvm,这个也很好用)
g、jhat(JDK自带)命令:分析 dump文件
拉到最下面,可以看到 其他查询(other queries),点进去得到类似于jmap的页面,显示了对象最多的类。
还有一个好玩更加强大的是这个自助查询功能。但很少用
输出各个类的对象,点进去就是对象的各个详细信息,不大常用。
h、jad命令:反编译
- :反编译主要用于:
- 动态代理生成类的问题定位
- 第三方的类(观察代码)
- 版本问题(确定自己最新提交的版本是不是被使用)
i、redefine命令:热替换
- redefine 热替换 主要用于:
目前有些限制条件:只能改方法实现(方法已经运行完成),不能改方法名, 不能改属性
案例如下
i、案例测试-目的
目标流程:写了一个TT类,调用T类打印数字1,执行TT类;在不停掉程序TT的情况下,将打印1改为打印2。
ii、代码
iii、启动Arthas ,监控TT小程序
iv、重新修改、编译T.java
新建终端,修改T.java ,将输出1 改为输出2;然后重新编译成字节码文件
学JAVA前c需要如何打基础
v、redefine热编译
vi、结果执行
- 回到程序执行的终端,进行打印。打印出2,说明热编译成功。redefine 命令的注意事项,看文档就可以啦。
- 现在建议使用 retransform 替换 redefine 命令
j、sc命令:查看 JVM 已加载的类信息
- https://arthas.aliyun.com/doc/sc.html
- sc:search class,查看 JVM 已加载的类信息
- 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的 ClassLoader 等详细信息。
如果一个类被多个 ClassLoader 所加载,则会出现多次
k、watch 命令:函数执行数据观测
- https://arthas.aliyun.com/doc/watch.html
- watch - watch method
- 没有包含的功能:jmap
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/19487.html