没长正的技术专栏 勤动手、多思考

JVM

2018-09-02

阅读:

2021-04-16

JVM

一、JVM组成

2021-04-14_JVM数据运行时

二、内存高-示例分析

内存溢出案例分析

1.示例分析

(本地设置最大堆内存,VisualVM的HeapDump 功能分析 或者基于IDEA 的 JProfiler分析)

1.在开发环境上,基于k8s 构建的服务,需要使用XXL-job调用, IJobHandler方式 (识别Bean、需要注册该服务到xxl-job)   

(1)自动识别容器内存限制(即可保证你的Java进程不会因为内存问题被容器Kill。) 默认1核4G  自动操作
		-XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 
(2)为了尽快分析定位问题,调小内存限制,尽快抛异常。设置JVM启动参数:  手动设置(-Xms -Xmx) ```java
	java -Dspring.profiles.active=dev -Xms128m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -verbose:gc -Xloggc:/data/logs/md-refresh-data-service/gc.log -jar /data/app.jar ```
  注:遇到时间不同步问题(重启服务解决 或者启动ntp时间同步服务) ```java
	com.xxl.rpc.util.XxlRpcException: The timestamp difference between admin and executor exceeds the limit. at ```

2.可以基本本机调式,将xxl-job 内容模拟为请求,然后通过jmeter 定时出发(并发测试);参考手动设置JVM -Xms -Xmx 方式,基于JProfiler 或VisualVM

常用方法:参考

2.分析过程:

<1.表象

​ 生产上应用不断爆出内存溢出,造成服务自动重启,该服务业务逻辑就是对外提供接口和刷新数据到MongoDB(基于XXL-JOB bean模式的定时任务);

随着定时任务的执行,内存逐渐增加,GC少。

<2.排查

​ 运维给出的内存使用信息(jmap -head )

2021-04-14_JVM数据运行时

<3.定位

​ 由于线上环境内存快满了,故本地模拟,复现该场景。为了尽快复现问题,本地设置启动参数为: -Xms128m -Xmx256m -XX:+HeapDumpOnOutOfMemoryError;xxl-job 设置每分钟跑一次(多个任务都设置为1分钟),大约10分钟就抛出内存溢出。

(基于IDEA的JProfiler插件)

2021-04-14_JVM数据运行时

​ 查看大对象信息(内存溢出一般是基于大对象引发的)

2021-04-14_JVM数据运行时

​ 双击查看大对象详情:

2021-04-14_JVM数据运行时

​ 展开,查看详情:

2021-04-14_JVM数据运行时

​ 最后分析出是基于MongoDB连接引发的;由于清理备份表每次都用0开始,然后清理至保存最后几份备份表,频繁操作mongodb,最终未释放掉相应的连接信息。

<4.解决

​ 优化方案:单独写了算法,清理除保留最近几份的表以外的几份备份表即可(通过Apollo配置方式设置)

三、CPU高,响应慢-示例分析

1.示例分析

不是keys,记一次因redis使用不当导致应用卡死的过程

实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep


#(1) 查询机器使用情况
  
  top

#(2)查询单个线程(较耗资源的线程)

  top -H -p 12798(pid)

#(3)jstack 查看堆内存
# 12799 的16进制字符串 
  print "0x%08x" 12798  # 0x000031fe
  jstack 12798 |grep 31fe

 #(4)查看前10行与后10行内容  => 可定位到具体代码行数

  jstack 12798 |grep 31fe -A 10 -B 10

四、CPU不高,响应慢

一般是死锁的场景

一般步骤:

  • jps 命令,查看java进程的pid
  • jstack 查看线程日志
如果存在死锁情况,Thread Dump日志里面肯定会给出Found one Java-level deadlock:信息。只要
找到这个信息就可以立马定位到问题并且去解决。

Found one Java-level deadlock:
=============================

参考文档

  • 《Java 虚拟机规范(Java SE 8版)》
  • 《深入理解 Java 虚拟机 第二版》
  • 《深入理解 Java 虚拟机 第三版》
  • 《实战 Java 虚拟机》

JDK8 doc

内存溢出案例分析

不是keys,记一次因redis使用不当导致应用卡死的过程

容器中的JVM资源该如何被安全的限制?

容器中的JVM资源该如何被安全的限制?

jstat和jmap命令查看JVM堆内存的使用情况

Java虚拟机(JVM)详解

新一代垃圾回收器ZGC的探索与实践


欢迎拍砖,多多交流,转载请注明出处:[没长正的技术专栏](http://blog.meizhangzheng.com) 如涉及侵权问题,请发送邮件到xsj34567@163.com,如情况属实本人将会尽快删除。


上一篇 JVM基础

下一篇 Docker安装

Comments

Content