首页 > 编程语言 >java服务OOM和CPU飙升排查

java服务OOM和CPU飙升排查

时间:2023-03-01 12:55:49浏览次数:35  
标签:java OOM XX 线程 内存 使用 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,XX,线程,内存,使用,CPU
From: https://www.cnblogs.com/sun2020/p/17167776.html

相关文章

  • flutter doctor错误:“Unable to find bundled Java version.”
    实际是找不到/Applications/AndroidStudio.app/Contents/jre/jdk执行如下命令:cd/Applications/AndroidStudio.app/Contents/ln-sjbrjrecdjreln-sContents......
  • IDEA在编译的时候报Error: java: 找不到符号符号: 变量 log lombok失效问题
    setting-->Build,Execution,Deployment 点击complier 在SharedbuildprocessVMoptions:中添加配置  -Djps.track.ap.dependencies=false ......
  • javaJDBC(finish)
    JDBC核心技术1.JDBC概述1.1数据的持久化持久化(persistence):把数据保存到可掉电式存储设备中以供之后的使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存......
  • Java面向对象部分重点笔记(二)
    Java面向对象部分重点笔记(二)接口 声明类的关键字是class,声明接口的关键字是interface 接口的作用:1.接口是一种约束2.定义一些方法,让不同的类实现3.接口中......
  • Java反射入门
    1.概述反射就是在运行状态,对于任意一个类,都可以直达这个类的属性和方法;对于任何一个对象,都可以调用它的任意一个方法和属性。而对于官方的解释是,反射允许对封装类的字段、......
  • java反射机制
    JAVA反射机制-----copy自p牛的java安全漫谈反射是⼤多数语⾔⾥都必不可少的组成部分,对象可以通过反射获取他的类,类可以通过反射拿到所有⽅法(包括私有),拿到的⽅法可以调⽤,......
  • [Java] 1.类和对象
    类和对象Class:类是对一类具有相同属性的事物的抽象。可以理解为类只是一张设计图。Object:对象是对类的实例化,就是按照类图纸,制造出来可操作的实体。类的定义class......
  • [Java] 2.封装
    封装封装就是要程序员学会正确设计类对象的属性和方法,举个例题:请对“人在加油站加200块汽油”进行面向对象设计。显然我们可以得到两个类人:classPerson{}加油......
  • Java导出word文档
    首先上测试代码,用的SpringMVC。/***测试导出word文档**@paramrequest*@return*@throwsCustomException*@authoryuanjin......
  • 33 个重要的 JavaScript 概念
    33个重要的JavaScript概念原创2022-12-2418:21·程序媛最幽默 了解这33个JavaScript概念绝对会让你将来的职业生涯受益无穷。话不多说,直接进入主题!1.调用栈......