解决内存泄漏问题

本文详细探讨了内存泄露的定义、问题影响,以及常见的内存泄露原因,包括变量作用域不合理、向静态集合添加数据、内部类引用、数据结构操作和连接未释放。同时提供了相应的解决策略,强调了在编程中避免内存泄露的重要性。

内存泄露

Java虚拟机是使用引用计数法和可达性分析来判断对象是否可回收,本质是判断一个对象是否还被引用,如果没有引用则回收。内存泄露是指,程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。简单来说,就是应该被垃圾回收的对象没有回收掉,导致占用的内存越来越多,最终导致内存溢出。

内存泄露主要原因:

  • 在内存中加载过大的数据,例如从数据库取出过多数据;
  • 资源未关闭造成的内存泄漏;
  • 变量不合理的作用域,使用完毕,如果没有及时的赋值为null,则会造成内存泄露;
  • 长生命周期的对象中引用短生命周期对象,很可能会出现内存泄露;

举个例子,创建的连接不再使用时,需要调用close方法关闭连接,只有连接被关闭后,GC才会回收对应的对象。忘记关闭这些资源会导致持续占有内存,无法被GC回收。这样就会导致内存泄露,最终导致内存溢出。

public class MemoryLeak {
    public static void main(String[] args) {
      try{
          Connection conn =null;
          Class.forName("com.mysql.jdbc.Driver");
          conn =DriverManager.getConnection("url","","");
          Statement stmt =conn.createStatement();
          ResultSet rs =stmt.executeQuery("....");
      } catch(Exception e){//异常日志
      } finally {
        // 1.关闭结果集 Statement
        // 2.关闭声明的对象 ResultSet
        // 3.关闭连接 Connection
    }
  }
}

排查过程

根据运维之前收集到的内存数据、GC日志尝试判断哪里出现了问题。结果发现老年代的内存使用就算是发生GC也一直居高不下,而且随着时间推移也越来越高。

在这里插入图片描述

使用jstat -gc <vmid> 查看GC垃圾回收统计信息,看Full GC后堆空间使用内存还持续增长,且有增长到Xmx设定值的趋势,基本可以肯定存在内存泄露。如果当前完全垃圾回收后内存增长到一个值之后,又能回落,总体上处于一个动态平衡,那么内存泄漏基本可以排除;也可以隔断时间抽取老年代占用内存情况,如果老年代占用情况持续上升也很有可能存在内存泄露的情况。

解决方案

  1. 内存泄漏的主要表象就是内存不足,所以首先要看一下JVM启动参数中内存空间分配是否过小,如果是这种问题调整该参数即可;
  2. 确定是否新部署或有新变更,首先需要确认是否在最近进行了新的部署或有其他相关的变更,例如代码更新、配置修改等。这些变更可能导致应用出现性能问题,特别是在高负载情况下;
  3. 内存泄漏解决方案,最经典的就是用MAT工具分析dump文件,但如果dump文件巨大就不建议这样,可以使用其他方案,例如:重启、本地复现、jmap -histo:live <pid>在线进行分析等其他方案解决。

使用MAT定位内存泄漏思路:

  1. 打开MAT中histogram,找到堆内存中占用最大的对象,内存泄漏很有可能就是由大对象导致的;
    在这里插入图片描述

  2. 由大对象找被哪些线程引用,查看内存占用最大的线程;
    在这里插入图片描述

    在这里插入图片描述

  3. 从线程中的堆栈信息找到项目中自定义的包和对象,从而可定位到具体的代码;

    在这里插入图片描述
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_whitepure

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值