解决


内存泄漏

于是赶快登陆探测服务器,首先是 top free df 三连,结果还真发现了些异常。

我们的探测进程 CPU 占用率特别高,达到了 900%。

我们的 Java 进程,并不做大量 CPU 运算,正常情况下,CPU 应该在 100~200% 之间,出现这种 CPU 飙升的情况,要么走到了死循环,要么就是在做大量的 GC。

使用 jstat -gc pid [interval] 命令查看了 java 进程的 GC 状态,果然,FULL GC 达到了每秒一次。

这么多的 FULL GC,应该是内存泄漏没跑了,于是 使用 jstack pid > jstack.log 保存了线程栈的现场,

使用 jmap -dump:format=b,file=heap.log pid 保存了堆现场,然后重启服务,报警邮件终于停止了。

jstat

jstat 是一个非常强大的 JVM 监控工具,一般用法是: jstat [-options] pid interval

它支持的查看项有:

  • -class 查看类加载信息
  • -compile 编译统计信息
  • -gc 垃圾回收信息
  • -gcXXX 各区域 GC 的详细信息 如 -gcold

使用它,对定位 JVM 的内存问题很有帮助。

排查

分析栈

栈的分析很简单,看一下线程数是不是过多,多数栈都在干嘛。

> grep 'java.lang.Thread.State' jstack.log  | wc -l
> 464

才四百多线程,并无异常。

> grep -A 1 'java.lang.Thread.State' jstack.log  | grep -v 'java.lang.Thread.State' | sort | uniq -c |sort -n

     10 	at java.lang.Class.forName0(Native Method)
10 at java.lang.Object.wait(Native Method)
16 at java.lang.ClassLoader.loadClass(ClassLoader.java:404)
44 at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
344 at sun.misc.Unsafe.park(Native Method)

线程状态好像也无异常,接下来分析堆文件。

下载堆 dump 文件。

堆文件都是一些二进制数据,在命令行查看非常麻烦,Java 为我们提供的工具都是可视化的,Linux 服务器上又没法查看,那么首先要把文件下载到本地。

由于我们设置的堆内存为 4G,所以 dump 出来的堆文件也很大,下载它确实非常费事,不过我们可以先对它进行一次压缩。

gzip 是个功能很强大的压缩命令,特别是我们可以设置 -1 ~ -9 来指定它的压缩级别,数据越大压缩比率越大,耗时也就越长,推荐使用 -6~7, -9 实在是太慢了,且收益不大,有这个压缩的时间,多出来的文件也下载好了。

使用 MAT 分析 jvm heap

MAT 是分析 Java 堆内存的利器,使用它打开我们的堆文件(将文件后缀改为 .hprof), 它会提示我们要分析的种类,对于这次分析,果断选择 memory leak suspect

从上面的饼图中可以看出,绝大多数堆内存都被同一个内存占用了,再查看堆内存详情,向上层追溯,很快就发现了罪魁祸首。

分析代码

找到内存泄漏的对象了,在项目里全局搜索对象名,它是一个 Bean 对象,然后定位到它的一个类型为 Map 的属性。

这个 Map 根据类型用 ArrayList 存储了每次探测接口响应的结果,每次探测完都塞到 ArrayList 里去分析,由于 Bean 对象不会被回收,这个属性又没有清除逻辑,所以在服务十来天没有上线重启的情况下,这个 Map 越来越大,直至将内存占满。

内存满了之后,无法再给 HTTP 响应结果分配内存了,所以一直卡在 readLine 那。而我们那个大量 I/O 的接口报警次数特别多,估计跟响应太大需要更多内存有关。

给代码 owner 提了 PR,问题圆满解决。

出处:https://www.cnblogs.com/zhenbianshu/p/10305428.html

内存泄漏学习案例-1-ArrayList的更多相关文章

  1. Java内存泄漏真实案例

    内存泄漏:当不再需要一个对象时,垃圾收集器会回收它:如果不需要的对象一直在产生而不被收回,就称作“内存泄漏”. 以下为本人在工作中遇到的内存泄漏的案例: 1.对于大量的请求,使用了Executors. ...

  2. Android - 看似内存泄漏,实则不是,记一次内存泄漏的案例分析

    APP中常常会存在内存泄漏的问题,一个简单的测试方法是,多次进入和退出同一页面(Activity),使用adb shell中的dumpsys meminfo com.android.settings ...

  3. Android内存溢出、内存泄漏常见案例及最佳实践总结

    内存溢出是Android开发中一个老大难的问题,相关的知识点比较繁杂,绝大部分的开发者都零零星星知道一些,但难以全面.本篇文档会尽量从广度和深度两个方面进行整理,帮助大家梳理这方面的知识点(基于Jav ...

  4. objective-c strong导致内存泄漏简单案例

    例如: @interface Test:NSObject{ id __strong obj_; } -(void) setObject:(id __strong)obj; @end @implemen ...

  5. python中循环引用导致内存泄漏小案例

    首先定义一个Person类和一个Dog类,然后分别实例化对象p和d,给p对象添加一个pet属性 给d对象添加一个master属性此时Person和Dog的应用计数都为2,当del p 和del d后P ...

  6. Node 内存泄漏排查案例

    背景 在阿里云上看到我运行了一段时间的程序,发现 memory 一项基本是在稳步提升,就知道有内存泄漏的情况出现.如下图 近三日从 35% 升到 40%,缓慢而坚定的提升. 代码 排查此问题需要分析其 ...

  7. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  8. Android 性能优化之内存泄漏检测以及内存优化(中)

    https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...

  9. Android - 通过真实案例学习解内存泄漏问题,最终发现Android原生Bug

    作为一个Android新手小白,刚到新公司,最近的工作就是在学习解各类Bug.转型之初,面临各种新知识,会有压力,但是学习的过程是快乐的. 上周刚遇上一类bug,就是应用的内存泄漏问题.最终通过前辈的 ...

随机推荐

  1. nginx——配置 Nginx 防盗链

    什么是防盗链:简单地说,就是某些不法网站未经许可,通过在其自身网站程序里非法调用其他网站的资源,然后在自己的网站上显示这些调用的资源,使得被盗链的那一端消耗带宽资源 (1) 根据 HTTP refer ...

  2. VBA在WORD应用中如何将格式应用于选定内容

    下列示例使用 Selection 属性将字符和段落格式应用于选定文本.使用 Font 属性获得字体格式的属性和方法,使用 ParagraphFormat 属性获得段落格式的属性和方法. Sub For ...

  3. 2Sum问题

    2Sum问题是3Sum和4Sum的基础,很多OJ都是以此为最简单的练手题的. 题目描述: 从一个数组里找出两个和为target的数. LeetCode上的描述: Given an array of i ...

  4. excel2013 打开为灰色空白 左下角显示就绪 要把文件拖进去才能打开!

    最近电脑excel2013 打开总是为灰色空白 左下角显示就绪 要把文件拖进去或者在此再打开一个才能打开! 在网上搜了一下,我是使用下面这个方法解决的: 步骤一:请您在“开始”菜单的搜索框中输入“re ...

  5. bind啊你返回的函数到底是个虾米

    一般apply().call()和bind()会一起比较. 他们三个都是改变this对象指向的方法. apply()和cal()方法是会立即执行,apply把参数作为数组,call方法接收一个一个的参 ...

  6. loadrunner的安装与破解

    https://pan.baidu.com/s/1H4Cj0ySTwqPra5OA3nicmw 背景: 由于想做服务器的性能测试,所以最近有意研究一下loadrunner这个工具,下面仅将安装过程做个 ...

  7. SharePoint 2013 解惑 无法打开文件浏览器

    你有时候会看到这东西谈出来,当你想像管理文件一样,管理SharePoint上资源的时候 意思是说,不能打开文件浏览器,请加入你的站点到信任站点,这个有两个问题,一个是IE设置,一个是WebClient ...

  8. GLog 初始化说明

    #include <iostream> #include <glog/logging.h> int main(int argc, char* argv[]) { google: ...

  9. golang的map

    map--字典 map的基本使用: package main import "fmt" // 先声明 type PersonInfo struct { id string name ...

  10. docker for windows 部署gitlab

    gitlab的安装相对繁琐,如果使用docker 镜像的方式就轻松太多了. 我是用的环境是windows10 专业版 + docker for windows 1.右键docker打开Kitemati ...