1.引子

今天聊一下OOM的问题。OOM就是Out Of Memory。前几天,线上出现过一次,频繁的full GC的问题。今天就简单记录一下排查的步骤。

2.模拟

在这只能模拟OOM。很简单,就是一个集合,写个循环向里面添加对象。这个方法:startThread2

import java.util.ArrayList;import java.util.List;class Test {    public static void main(String[] args) {        if (args.length == 0) {            System.out.println("运行的时候请输入参:1 or 2");            return;        }        if (args[0].equalsIgnoreCase("1")) {            startThread1();        }        if (args[0].equalsIgnoreCase("2")) {            startThread2();        }    }    public static void startThread1() {        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    String a = new String("deadThread");//System.out.println(a);                }            }        });        thread.setName("deadThread");        thread.start();    }    public static void startThread2() {        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                List list = new ArrayList<>();                while (true) {                    String a1 = new String("OOMThread");                    list.add(a1);                }            }        });        thread.setName("OOMThread");        thread.start();    }}

3.编译运行

javac test.java

javac test.java

java -Xms10m -Xmx10m -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ Test 2

注:

-Xms10m -Xmx10m 初始堆大小和最大堆大小。 这里是模拟,所以设置小一点

-XX:+PrintGC -XX:+PrintGCDetails 打印一下GC的日志

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ 当发送OOM的时候,自动保存Dump文件。后面那个是报错的路径,如果没有则,在当前目录下。

已运行会一直打gc日志,因为死循环在添加对象,并且对象还没法回收。

一会就会内存溢出,如下图

4分析dump文件

发生OOM了。接着就是要分析一下这个dump文件了。分析的工具有很多,这里使用mat和jvisualvm分别分析一下,其实都差不多。

首先,从服务器下载到本地。然后使用工具就行分析。

1.首先使用MAT分析:

打开mat,导入hprof文件。(注:如果hprof文件特别的大,需要调整一下mat的内存参数。防止内存溢出,打不开文件)

mat

我们可以看到mat已经帮我们分析到了一个错误:

点击details详情。会发现:

线程 OOMThread中一个ArrayList占了98.12%,而它里面放的是String对象。

注:这里面有两个比较难理解的名词(我理解的不一定完全对。大家可以自行百度一下):

1.shallow heap:shallow:浅的,我理解就是:这个对象实际占用的堆大小

2.retained heap:retained:保留的,这个有点难理解了:简单的话,就是它和它引用的对象(这里的引用对象没有被其他的对象引用)的占用堆的大小。(不知道理解的对不对。)如下图:arrayList中shallow是24,retained是9057600.以为我newString的都放到list中去了。

初步怀疑是ArrayList中对象过多,一直有引用,没有被gc回收导致。然后看一下抛出OOM的异常的地方。发现有对应的ArrayList。它有一个循环在一直添加String对象。

2.使用jvisualvm.exe

打开jvisualvm.exe,导入hprof文件。

在出现 OutOfMemoryError 异常错误时进行了堆转储导致 OutOfMemoryError 异常错误的线程: OOMThread

点击:OOMThread

显示是在什么地方发生的OOM,然后点击 红框的地方。

我们可以发现:arrayList的size大小为:317374. 猜测是arrayList结合中对象太多。由此可以去查对应的代码逻辑判断。

还可以点击类:会显示对象的个数和占比。会发现string对象,有318309个实例,占所有实例中99.1%,大小是8912652,占用了堆74.2%的空间

注:实际生产中情况,比这个要复杂,不过大概分析过程就是这样。其实频繁的fullgc也可以导出dump文件去分析。是不是有内存泄漏的地方。当然,一般大公司会有相应的监控系统,在堆空间超过某个阈值就会报警,这个时候,可以将这台机器从vip摘除或者(healthcheck先摘除了)这样Nginx就打不过来,就不会有用户的请求过来了。然后使用jmap导出dump文件分析。这个以后有时间再讲。

循环上传导致oom_java之OOM排查相关推荐

  1. 解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题

    解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题 问题描述 java程序,使用阿里云oss文件上传服务,在测试时偶然发现,我用苹果手机开启高清进行摄像,将原图通过qq传到电脑上,在电 ...

  2. 大神论坛 UEditor 富文本web编辑器最新漏洞版XML文件上传导致存储型XSS

    一.Ueditor最新版XML文件上传导致存储型XSS 测试版本:php版 v1.4.3.3 下载地址:https://github.com/fex-team/ueditor 复现步骤: 1. 上传一 ...

  3. 线上服务导致cpu飙升问题排查

    一.故障说明 昨晚突然收到线上服务器cpu报警,登录监控平台看了下发现cpu瞬间飙升到60%.第一反应就是使用top命令去查看,发现是一个java进程.于是立刻使用jps -l命令定位到该java进程 ...

  4. V3S拍照上传又拍云bug排查过程

    1.确保收到mqtt命令后去生效抓图标志. void CreateOpenDoorJpgName(void *recordData) {     int i;     int ret;     uns ...

  5. nginx 上传 文件超时设置_Nginx大文件上传413和500问题排查总结

    背景 前几天上传一个300MB的文件,发现报错,这里说明一下,用户的请求会通过Nginx代理(负载均衡)到应用服务器. 413问题解决 错误信息为"413 Request Entity To ...

  6. 通过Ftp put命令上传导致文件损坏的解决办法

    通过Linux命令行向在一台Windows FTP服务器上传文件.然后在另一台Windows客户机登录FTP服务器下载,但是下载后的文件大小变了,exe文件错误了不能正确执行.刻意打包的文件(.rar ...

  7. PHPYUN任意文件上传导致GETSHELL

    简要描述: 简单到你难以想象,只要网站还可以注册就可以GETSHELL,无视GPC,无视WAF.4.1beta版本,其他版本未测 详细说明: 1.在审计PHPYUN的时候一度对PHPYUN的WAF非常 ...

  8. 本地终端通过ftp put命令上传导致文件损坏的解决办法(无语)

    通过终端命令行向在一台Windows FTP服务器上传图片.服务器里面有东西了,但是打开后的图片变了(法克-----马赛克),呵呵呵(失真了),额.........应该是文件损坏了吧. 经过搜索发现一 ...

  9. 压缩包文件上传导致覆盖rce

    制作恶意压缩包 tgao.jsp文件内容: <html> <body><%out.println("zip slip getshell.");%> ...

最新文章

  1. 一文读懂卷积神经网络
  2. Mybatis接口Mapper内的方法为啥不能重载吗?
  3. suse 11 oracle 10g,suse11+oracle10g安装
  4. canvas动画 电子白板_广东智慧电容式触摸屏维修,学校电子白板操作
  5. 跟我学jQuery(二) 初识jQuery
  6. java calendar_Java Calendar complete()方法与示例
  7. Java 随心笔记7
  8. vs调用css写的c语言程序,c语言文件读写实例
  9. fgetc与EOF的错综复杂关系
  10. Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
  11. HttpClient连接池的连接保持、超时和失效机制
  12. 解决nginx端口占用问题
  13. mysql建立聚族索引语句,MySQL学习教程之聚簇索引
  14. Kafka 集群搭建
  15. 华为交换机dhcp获取不到_华为S7706交换机DHCP Server 配置不成功问题
  16. 推荐系统 - 排序算法 - 神经网络:FNN 论文阅读
  17. 【游戏客户端开发】Unity3D 学习笔记2——了解U3D引擎的操作面板和各种工具
  18. 使用C#解线性回归方程
  19. Vue3中使用Ant Design Vue图标
  20. 从最简单的ROE和PB的角度去选股

热门文章

  1. 使用idea 打jar包
  2. mysql左连接_面试考MySQL性能优化,一个问题就干趴下了!
  3. 浅谈K短路算法(KSP)之二(YEN .J算法求解)
  4. 8 reasons why SPIR-V makes a big difference
  5. Vue中ESlint配置文件eslintrc.js文件详解
  6. Ubuntu 16.04安装MySQL(5.7.18)
  7. 在mysql命令行下执行sql文件
  8. C语言OJ项目参考(1915) 第几天
  9. oracle10g遇到ORA-16038日志无法归档问题
  10. Linux救援模式实战