java服务OOM和CPU飙升排查
一、JVM参数
- -D 可以是系统默认有的参数,也可以是自己定义的参数
-Dfile.encoding=UTF-8
-Dmaven.test.skip=true
-Dspring.profiles.active=test
-Dhsf.server.port=12404
-Dhsf.http.port=12402
- 堆内存参数
-Xmx5M 指定最大堆内存。 如 -Xmx4g。这只是限制了 Heap 部分的最大值为4g。这个内存不包括栈内存,也不包括堆外使用的内存,默认是物理内存的1/4。
-Xms5M 指定堆内存空间的初始大小。 如 -Xms4g。 而且指定的内存大小,并不是操作系统实际分配的初始值,而是 GC 先规划好,用到才分配。 专用服务器上需要保持 –Xms 和 –Xmx 一致,否则应用刚启动可能就有好几个FullGC。当两者配置不一致时,堆内存扩容可能会导致性能抖动,默认是物理内存的1/64。
-Xmn: 设置年轻代大小,等价于 -XX:NewSize,使用 G1 垃圾收集器不应该设置该选项,在其他的某些业务场景下可以设置。官方建议设置为 -Xmx 的 1/2 ~ 1/4。
-Xss:设置每个线程栈的字节数,影响栈的深度。例如 -Xss1m 指定线程栈为1MB,与-XX:ThreadStackSize=1m 等价。
GC 设置参数
-XX:+UseG1GC:使用 G1 垃圾回收器。
-XX:+UseConcMarkSweepGC:使用 CMS 垃圾回收器。
-XX:+UseSerialGC:使用串行垃圾回收器。
-XX:+UseParallelGC:使用并行垃圾回收器。
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC: jdk 11 以上开启 ZGC.
-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC:jdk 12 以上开启 ShenandoahGC。
- 分析诊断参数
-XX:+HeapDumpOnOutOfMemoryError:当 OutOfMemoryError 产生,即内存溢出(堆内存或持久代/元空间) 时,自动 Dump 堆内存。
-XX:HeapDumpPath:与 HeapDumpOnOutOfMemoryError 搭配使用,指定内存溢出时 Dump 文件的目录。如果没有指定则默认为启动 Java 程序的工作目录。
java -Xmx5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/log/dump HeapOOM
自动 Dump 的 hprof 文件会存储到 /log/dump 目录下。
二、内存溢出排查

导致内存溢出的原因:
- 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
- 资源使用之后没有及时关闭,导致对象无法被GC回收;
- 代码中存在死循环或循环产生过多重复的对象实体;
- 启动参数内存值设定的过小;
1. 测试内存溢出的代码:
@RestController
@RequestMapping
public class OOMDemoController {
class OOMObject {
}
@GetMapping("/oom/heap")
public void OOMHeap() {
List<OOMObject> list = new ArrayList<>();
while (true) {
list.add(new OOMObject());
}
}
}
2.启动的时候设置堆内存大小和产生OOM的时候dump文件的输出:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/sun/Desktop -Xms10m -Xmx50m
3.调用/oom/heap接口就会堆内存溢出,此时桌面会生成一个java_pid1234.hprof的文件,然后用MAT工具打开该文件

点击工具栏上的
图标可以打开Histogram(直方图)视图,可以列出每个类产生的实例数量,以及所占用的内存大小和百分比。主界面如下图所示:

图中Shallow Heap 和 Retained Heap分别表示对象自身不包含引用的大小和对象自身并包含引用的大小;
其实从图中占用内存大小排序后,基本上就能看到那个类产生了OOM,然后从代码的角度去排查一下就好了,更加详细的MAT使用教程,可参考https://www.javatang.com/archives/2017/11/08/11582145.html
三、Java服务CPU飙升排查
@RestController
@RequestMapping
public class OOMDemoController {
@GetMapping("/cpu")
public void cpu() {
while (true) {
}
}
}
- 使用top命令找出CPU最高的进程PID
- 使用jps命令找出对应的java程序
- 使用top -H -p pid单独查看该进程的所有线程nid,此时nid是10进制,-H是进行排序
- 找到CPU占用最高的线程号,然后转换为16进制,可以使用printf "%x\n" pid打印出来
- 使用jstack -l [pid] | grep -A 20 [16进制线程号] (jstack -l 62170 | grep -A 20 f2da)

- 可以输出到文件中查看jstack -l [pid] jstackLog.out
- 根据WAITING或者BLOCKED大致判断是死循环还是死锁,然后回到程序中定位代码并且根据业务场景解决
java服务OOM和CPU飙升排查的更多相关文章
- JAVA服务实例内存高问题排查及解决
生产服务内存高问题 问题描述 1."计算中心" 服务在生产环境运行一段时间后,实际占用内存4.8G,业务运行正常,未出现OOM.(本文以此服务进行排查) 2.生产环境的老项目,均出 ...
- CPU飙升排查
怎么排查CPU飙升 线上有些系统,本来跑的好好的,突然有一天就会出现报警,CPU使用率飙升,然后重启之后就好了.例如,多线程操作一个线程不安全的list往往就会出现这种现象.那么怎么定位到具体的代码范 ...
- 记一次CPU飙升BUG
图文地址:https://mp.weixin.qq.com/s?__biz=Mzg3NjEzODQ4NQ==&mid=2247483690&idx=1&sn=7c926f400 ...
- 开会时CPU 飙升100%同事们都手忙脚乱记一次应急处理过程
告警 正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误.查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%. 赶紧从会上下来,SSH登录 ...
- Java服务CPU飙到99%问题排查
最近生产环境中出现了一起CPU突然飙升的事件,下面介绍一下 CPU飙升问题排查的过程和解决方法. 该方案参考自:https://www.jianshu.com/p/e96c74133be6,感谢路遥N ...
- 【转】Java程序CPU飙升问题排查方法
windows环境下cpu飙升问题 线上某台runtime机器(windows Server)cpu报警,这种情况初步就是代码里面死循环了,先把机器下线了保证不再有新的任务分配进来,然而cpu使用依然 ...
- Java死锁排查和Java CPU 100% 排查的步骤整理
================================================= 人工智能教程.零基础!通俗易懂!风趣幽默!大家可以看看是否对自己有帮助! 点击查看高清无码教程 == ...
- 线上CPU飙升100%问题排查,一篇足矣
一.引子 对于互联网公司,线上CPU飙升的问题很常见(例如某个活动开始,流量突然飙升时),按照本文的步骤排查,基本1分钟即可搞定!特此整理排查方法一篇,供大家参考讨论提高. 二.问题复现 线上系统突然 ...
- 面试连环炮系列(八):服务器CPU飙升100%怎么排查
服务器CPU飙升100%怎么排查 执行"top"命令,查看当前进程CPU占用的实时情况,PID列是进程号,确定是哪个应用程序的问题. 如果是Java应用导致的,怎么定位故障原因 执 ...
- Java服务,内存OOM问题如何快速定位? (转)
转自:公众号 架构师之路 问题:有一个Java服务出现了OOM(Out Of Memory)问题,定位了好久不得其法,请问有什么好的思路么? OOM的问题,印象中之前写过,这里再总结一些相对通用的方 ...
随机推荐
- 6.6 Windows驱动开发:内核枚举Minifilter微过滤驱动
Minifilter 是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的sfilter文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微过滤驱动使 ...
- C/C++ 实现FTP文件上传下载
FTP(文件传输协议)是一种用于在网络上传输文件的标准协议.它属于因特网标准化的协议族之一,为文件的上传.下载和文件管理提供了一种标准化的方法,在Windows系统中操作FTP上传下载可以使用WinI ...
- 联想T30瘦客户机安装DoraOS体验
硬件配置:J4125 .8G RAM. 128G ROM 联想T30台式电脑,它是一台迷你计算机,尺寸小巧玲珑,重量适中,方便携带.它的性能十分强大,能够运行各种应用程序,包括网页浏览器.视频播放器等 ...
- .NET 云原生架构师训练营(模块二 基础巩固 日志)--学习笔记
2.2.2 核心模块--日志 ILogger 的使用 日志的 ID 日志的分类 日志的级别 LoggerProvider 日志的最佳实践 .NET Core 和 ASP.NET Core 中的日志记录 ...
- ABC 304
T4 在一个平面上有一块面积无限的蛋糕,给出 \(n\) 颗草莓的所在位置和 \(a\,(b)\) 条平行与 \(x\,(y)\) 轴的切刀位置. 切刀会把蛋糕沿 \(x\,(y)\) 轴切开.因此一 ...
- 多线程系列(二) -Thread类使用详解
一.简介 在之前的文章中,我们简单的介绍了线程诞生的意义和基本概念,采用多线程的编程方式,能充分利用 CPU 资源,显著的提升程序的执行效率. 其中java.lang.Thread是 Java 实现多 ...
- SATA学习笔记——OOB信号
一.SATA物理层概述 说OOB之前,首先得了解一下SATA结构以及物理层的含义. SATA主要包括:应用层(Application Layer), 传输层(Transport Layer),链路层( ...
- 端口碰撞Port Knocking和单数据包授权SPA
端口碰撞技术 Port knocking 从网络安全的角度,服务器开启的端口越多就越不安全,因此系统安全加固服务中最常用的方式,就是先关闭无用端口,再对提供服务的端口做访问控制.而作为远程管理与维护的 ...
- numpy数组初始化方法总结
1 使用list初始化 a=np.array([[1,2,3],[4,5,6]],dtype='float32') #a=[[1. 2. 3.],[4. 5. 6.]] 2 赋值与复制 (1)赋值 a ...
- python中矩阵切片维数微秒变化
1 前言 使用切片访问矩阵的部分数据(特别是一行或一列数据)时,通常会出现切片维数怎么在瞎变化,以致于不得不用reshape()强制改变维数.在深度学习中,网络对矩阵维数的要求是非常严格的,往往就是这 ...