zoukankan      html  css  js  c++  java
  • 一次内存泄露排查

    故事背景

      cpu持续走高,直接导致服务器宕机,无法对外提供服务。

    排查思路  

      1. 一般cpu过高只有两种情况:1.线程太多,可以用命令看一下;2.频繁full gc,因为full gc是很消耗cpu资源的。
      2. 用jstat命令看了下,果然是频繁full gc造成的。但是内存分配比例和大小还是很合理的。新生代10g,老年代10g,可是每次ygc后都有1g左右对象去到老年代
      3. 基于上述情况、那这时候调整内存比例也不会有任何意义了,猜想是内存泄露引起的。因为老年代停留了大量对象无法回收,每次稍微ygc过来一点对象就会引起fgc

      于是就生成内存快照进行分析下  jmap -dump:format=b,file=demo.hprof  PID

      

    内存泄漏

      1. 下载mat工具 https://www.eclipse.org/mat/downloads.php
      2. 直接打开MemoryAnalyzer.exe就好了。(MemoryAnalyzer.ini文件默认限制了-Xmx1024m,一般生产环境导出的demp很大的,可以把这个调大一点)
      3. file -> open heap dump -> 选择刚才的快照文件就好了

       4. Problem Suspect 1 已经说的很清楚了 java.lang.Thread @ 0xe3805d30 main  线程的java.lang.Object[]占用了53.85%内存对象。

      点击 Details 可以看到 Accumulated Objects in Dominator Tree  的main线程中引用了一个 java.util.ArrayList ,他是一个java.lang.Object[]数组,里面全是demo1对象

      点击 See stacktrace 就能看到线程执行代码堆栈的调用链

      说白了,就是一次性加载过多数据到内存里来导致的,可以考虑数据分批处理或者多个线程并发执行。

    什么是内存泄漏及如何避免

         内存泄漏即:对象可达但不可用,程序不需要用某个对象,但另一个正在使用的对象却持有它的引用,导致无法回收停留在堆内中。

         防止内存泄露:

          1.尽早释放无用对象的引用, 将不需要使用的对象设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄漏。  

          2.程序进行字符串处理时,尽量避免使用String,而应该使用StringBuffer。

            3.尽量少用静态变量

          4.尽量运用对象池技术以提高系统性能

  • 相关阅读:
    君の知らない物語
    2.OSI各层概述
    [ unittest ] 使用初体验
    1.分层结构、协议、接口、服务
    [flask] jinja自定义filter来过滤html标签
    [Flask] Flask问题集(后端模板渲染项目)
    [服务器部署] Flask + virtualenv + uWSGI + Nginx 遇到的问题
    android控件的对齐方式(转)
    AIDL
    歌词的获取
  • 原文地址:https://www.cnblogs.com/wlwl/p/14395378.html
Copyright © 2011-2022 走看看