网站首页 > 博客文章 正文
当我们的系统上线之后,就需要对线上系统的JVM进行监控,这个监控通常来说有两种办法。
第一种监控方法
就是使用监控软件如:Zabbix、Prometheus、OpenFalcon、Ganglia、CAT、jarBoot等。它们都可以把JVM统计项发送到这些监控系统里去,可视化展现。
我们可以通过这些监控系统可视化的界面里,看到应用系统需要的所有指标,包括各个系统各个内存区域的对象占用变化曲线,直接可以看到Eden区的对象增速,还会告诉你YoungGC发生的频率以及耗时,包括老年代的对象增速以及Full GC的频率和耗时。而且这些工具还允许你设置监控。也就是说,你可以指定一个监控规则,比如线上系统的JVM,如果10分钟之内发生5次以上Full GC,就需要发送报警给你。比如发送到你的邮箱、短信里,这样你就不用自己每天去看着了。
当然了这些软件系统并不是每个公司都有,如果没有该如何监控呢,这就用到了第二种监控方案。
第二种监控方法
就是每天在高峰期和低峰期都用jstat、jmap、jhat等工具去看看线上系统的JVM运行是否正常,有没有频繁Full GC的问题。如果有就优化,没有的话,平时每天都定时去看看,或者每周都去看看即可。
- jstat
平时我们对运行中的系统,要检查他的JVM的整体运行情况,比较实用的工具之一,就是jstat,它可以轻易的让你看到当前运行中的系统,他的JVM内的年轻代(Eden、Survivor)和老年代的内存使用情况,还有Young GC和Full gC的执行次数以及耗时。
下面我们看看这个jstat工具。
jstat -gc PID 可以看到这个Java进程(其实本质就是一个JVM)的内存和GC情况了。
S0C:这是From Survivor区的大小
S1C:这是To Survivor区的大小
S0U:这是From Survivor区当前使用的内存大小
S1U:这是To Survivor区当前使用的内存大小
EC:这是Eden区的大小
EU:这是Eden区当前使用的内存大小
OC:这是老年代的大小
OU:这是老年代当前使用的内存大小
MC:这是方法区(永久代、元数据区)的大小
MU:这是方法区(永久代、元数据区)的当前使用的内存大小
YGC:这是系统运行迄今为止的Young GC次数
YGCT:这是Young GC的耗时
FGC:这是系统运行迄今为止的Full GC次数
FGCT:这是Full GC的耗时
GCT:这是所有GC的总耗时
除了上面的jstat -gc命令是最常用的以外,他还有一些命令可以看到更多详细的信息,如下所示:
jstat -gccapacity PID:堆内存分析
jstat -gcnew PID:年轻代GC分析,这里的TT和MTT可以看到对象在年轻代存活的年龄和存活的最大年龄
jstat -gcnewcapacity PID:年轻代内存分析
jstat -gcold PID:老年代GC分析
jstat -gcoldcapacity PID:老年代内存分析
jstat -gcmetacapacity PID:元数据区内存分析
其实,jstat工具主要是为了得到以下指标:新生代对象增长的速率,Young GC的触发频率,Young GC的耗时,每次Young GC后有多少对象是存活下来的,每次YoungGC过后有多少对象进入了老年代,老年代对象增长的速率,Full GC的触发频率,Full GC的耗时。
- jmap
使用jmap可以了解系统运行时的内存区域。
其实如果单单只是要了解JVM的运行状况,然后去进行JVM GC优化,通常来说jstat就完全够用了,但是有的时候可能我们会发现JVM新增对象的速度很快,然后就想要去看看,到底什么对象占据了那么多的内存。主要是找出问题代码,避免那种对象对内存占用过大,对OOM的情况进行防患于未然。
jmap -heap PID
这个命令可以打印出来一系列的信息,里面的东西大家自己看字面意思都能看懂的,主要是打印出来堆内存相关的一些参数设置,然后就是当前堆内存里的一些基本各个区域的情况,比如Eden区总容量、已经使用的容量、剩余的空间容量,两个Survivor区的总容量、已经使用的容量和剩余的空间容量,老年代的总容 量、已经使用的容量和剩余的容量。其实这些信息,用jstat命令也可以显示出来,所以一般不会用jmap去看这些信息,毕竟他信息还没jstat全呢,因为没有gc 相关的统计。
jmap -histo PID
这个命令是jmap里最有用的,它会按照各种对象占用内存空间的大小降序排列,把占用内存最多的对象放在最上面。所以如果只是想要简单了解一下当前jvm中的对象对内存占用的情况,只要直接用jmap -histo命令即可,非常好用。它可以让你快速了解到当前内存里到底是哪个对象占用了大量的内存空间。
JVM优化
我们通过各种监控工具摸清了JVM的运行情况,最终的目的还是为了优化。真正的优化,必须是根据自己的系统,实际观察之后,然后合理调整内存分布,没什么固定的JVM优化模板。
尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。合理调整新生代、老年代、Eden、Survivor各个区域的内存大小,保证对象尽量留在年轻代,不要过快进入老年代中。
总结出一句话:尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。
压力测试是一个很重要的环节,通常在这个环节,会使用一些压力测试工具(如JMeter),模拟1000个用户同时访问系统,造成每秒500个请求的压力,然后看系统能否支撑住每秒500请求的压力。同时看系统各个接口的响应延时是否在比如200ms之内,也就是接口性能不能太慢,或者是在数据库中模拟出来百万级单表数据,然后采用jstat工具来分析JVM的整体运行状。
借助jstat的各种功能分析出来以下JVM的关键运行指标:新生代对象增长的速率,Young GC的触发频率,Young GC的耗时,每次Young GC后有多少对象是存活下来的,每次Young GC过后有多少对象进入了老年代,老年代对象增长的速率,Full GC的触发频率,Full GC的耗时。如果发现对象过快进入老年代,可能是因为年轻代太小导致频繁Young GC,然后Young GC的时候很多对象还是存活的,结果Survivor也太小,导致很多对象频繁进入老年代。
当压测环境下的系统优化好JVM参数之后,观察Young GC和Full GC频率都很低,此时就可以部署系统上线了。
在JVM内存分配中,有几个参数是比较核心的,如下所示:
-Xms:Java堆内存的大小
-Xmx:Java堆内存的最大大小
-Xmn:Java堆内存中的新生代大小,扣除新生代剩下的就是老年代的内存大小了
-XX:PermSize:永久代大小
-XX:MaxPermSize:永久代最大大小
-Xss:每个线程的栈内存大小
- 上一篇: 如果在线上遇到了OOM,该如何解决?
- 下一篇: 大吉大利:空投十个JVM核心知识点,速度捡包
猜你喜欢
- 2024-09-18 3分钟搞清楚 JVM逃逸分析(java 逃逸对象)
- 2024-09-18 天天都是面对对象编程,你真的了解你的对象吗?
- 2024-09-18 做JAVA开发的同学一定遇到过的爆表问题,看这里解决
- 2024-09-18 线上一次fullgc搞得鸡飞狗跳后,我总结了这篇文章
- 2024-09-18 Java中的对象都是在堆上分配的吗?
- 2024-09-18 jvm 相关的线上问题,内存使用率飙升到 90%+ 等 处理手段
- 2024-09-18 面试官问我JVM问题,我直接回怼他
- 2024-09-18 JVM入门第2部分-调试内存问题(jvm内存调优方法)
- 2024-09-18 互联网大厂面试系列-面试被问到什么是JVM的逃逸分析?
- 2024-09-18 内存溢出OutOfMemoryError科普系列一
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)