iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java内存泄漏问题排查与解决
  • 227
分享到

Java内存泄漏问题排查与解决

2024-04-02 19:04:59 227人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

前言 Java 最牛逼的一个特性就是垃圾回收机制,不用像 c++ 需要手动管理内存,所以作为 Java 程序员很幸福,只管 New New New 即可,反正 Java 会自动回收过

前言

Java 最牛逼的一个特性就是垃圾回收机制,不用像 c++ 需要手动管理内存,所以作为 Java 程序员很幸福,只管 New New New 即可,反正 Java 会自动回收过期的对象。。。

那么 Java 都自动管理内存了,那怎么会出现内存泄漏,难道 JVM 有 bug? 不要急,且听我慢慢道来。。

1. 怎么判断可以被回收

先了解一下 Jvm 是怎么判断一个对象可以被回收。一般有两种方式,一种是引用计数法,一种是可达性分析。

引用计数法:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。

这个办法看起来挺简单的,但是如果出现 A 引用了 B,B 又引用了 A,这时候就算他们都不再使用了,但因为相互引用 计算器=1 永远无法被回收。

此方法简单,无法解决对象相互循环引用的问题。

可达性分析(Reachability Analysis):从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的,那么虚拟机就判断是可回收对象。

可达性分析可以解决循环引用的问题。

那么 gc roots 对象是哪些呢

虚拟机栈中引用的对象

方法区中类静态属性引用的对象

方法区中常量引用的对象

本地方法栈中JNI[即一般说的Native]引用的对象

目前主流的虚拟机中大多使用可达性分析的方式来判定对象是否可被 GC 回收。

2. 什么情况下会出现内存泄漏

既然可达性分析好像已经很牛逼的样子了,怎么可能还会出现内存泄漏呢,那我们再来看一下内存泄漏的定义。

内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。

有可能此对象已经不使用了,但是还有其它对象保持着此对象的引用,就会导致 GC 不能回收此对象,这种情况下就会出现内存泄漏。

写一个程序让出现内存泄漏

①长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收。

public class Simple {
    Object object;
    public void method1(){
        object = new Object();
        //...其他代码
    }
}

这里的 object 实例,其实我们期望它只作用于 method1() 方法中,且其他地方不会再用到它,但是,当method1()方法执行完成后,object 对象所分配的内存不会马上被认为是可以被释放的对象,只有在 Simple 类创建的对象被释放后才会被释放,严格的说,这就是一种内存泄露。

解决方法就是将 object 作为 method1() 方法中的局部变量。

public class Simple {
    Object object;
    public void method1(){
        object = new Object();
        //...其他代码
        object = null;
    }
}

当然大家有可能会想就这一个方法也不会有多大影响,但如果在某些项目中,一个方法在一分钟之内调用上万次的时候,就会出现很明显的内存泄漏现象。

集合中的内存泄漏,比如 HashMap、ArrayList 等,这些对象经常会发生内存泄露。比如当它们被声明为静态对象时,它们的生命周期会跟应用程序的生命周期一样长,很容易造成内存不足。

下面给出了一个关于集合内存泄露的例子。

Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
    Object o=new Object();
    v.add(o);
    o=null;
}
//此时,所有的Object对象都没有被释放,因为变量v引用这些对象。

在这个例子中,我们循环申请 Object 对象,并将所申请的对象放入一个 Vector 中,如果我们仅仅释放引用本身,那么 Vector 仍然引用该对象,所以这个对象对 GC 来说是不可回收的。

因此,如果对象加入到 Vector 后,还必须从 Vector 中删除,最简单的方法就是将 Vector 对象设置为 null。

以上两种是最常见的内存泄漏案例。当然还有一些内存泄漏的例子,这里就不再一一例举了,感兴趣的同学可以在网上找找资料。

3. 如何检测内存泄漏

3.1 模拟内存泄漏代码

package com.wenxiaowu.solution;
 
import java.util.ArrayList;
import java.util.List;
 

public class TestMemoryLeak {
    public static void main(String[] args) throws InterruptedException {
        List<SimpleObject> list = new ArrayList<>();
        Runtime run = Runtime.getRuntime();
        int i = 1;
 
        while (true) {
            SimpleObject simpleObject = new SimpleObject();
            list.add(simpleObject);
            simpleObject = null;
 
            if (i++ % 1000 == 0) {
                System.out.print(i + ": 最大内存=" + run.maxMemory() / 1024 / 1024 + "M,");
                System.out.print("已分配内存=" + run.totalMemory() / 1024 / 1024 + "M,");
                System.out.print("剩余空间内存=" + run.freeMemory() / 1024 / 1024 + "M");
                System.out.println("最大可用内存=" + (run.maxMemory() - run.totalMemory() + run.freeMemory()) / 1024 / 1024 + "M");
            }
            Thread.sleep(1);
        }
    }
}
 
class SimpleObject {
    // 初始化占用1M内存的数组
    private int[] arr = new int[1024 * 8];
    public int[] getArr() {
        return arr;
    }
}

3.2 生成dump文件

java -jar -Xmx1G -Xms1G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp wenxiaowu-java.jar

3.3 用JProfile加载dump文件

可以看到,红框处的int数组占用空间最大

3.4 定位最大占用内存的原始位置

最终找到这个对象是在main方法中创建的。

解决办法 

使用完之后,先删除对应的引用,再将对象置为null,即可正常进行内存回收。

总结

到此这篇关于Java内存泄漏问题排查与解决的文章就介绍到这了,更多相关Java内存泄漏内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java内存泄漏问题排查与解决

本文链接: https://www.lsjlt.com/news/163861.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java内存泄漏问题排查与解决
    前言 Java 最牛逼的一个特性就是垃圾回收机制,不用像 C++ 需要手动管理内存,所以作为 Java 程序员很幸福,只管 New New New 即可,反正 Java 会自动回收过...
    99+
    2024-04-02
  • linux内存泄漏问题怎么排查
    要排查Linux中的内存泄漏问题,可以按照以下步骤进行:1. 监控内存使用情况:使用工具如top、free或htop等监控系统的实时...
    99+
    2023-10-21
    linux
  • java内存泄漏问题怎么解决
    这篇文章主要介绍“java内存泄漏问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java内存泄漏问题怎么解决”文章能帮助大家解决问题。1、概念Java中的内存泄露是指不再使用的对象的内存...
    99+
    2023-06-30
  • 如何解决JAVA内存泄漏问题
    本篇内容介绍了“如何解决JAVA内存泄漏问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录什么是内存泄漏内存泄漏的原因内存泄漏有哪些情况...
    99+
    2023-06-20
  • java内存泄漏怎么排查
    Java内存泄漏是指在程序运行过程中,不再使用的对象仍然占用着内存空间,导致内存无法被回收。以下是一些常见的排查内存泄漏的方法:1....
    99+
    2023-08-31
    java
  • Java的内存泄漏问题怎么解决
    本篇内容介绍了“Java的内存泄漏问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一问题的提出Java的一个重要优点就是通过垃圾收...
    99+
    2023-06-03
  • Java内存泄漏的排查分析
    本篇内容介绍了“Java内存泄漏的排查分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、由来前些日子小组内安排值班,轮流看顾我们的服务,...
    99+
    2023-06-02
  • 怎么解决内存泄漏问题
    本篇内容介绍了“怎么解决内存泄漏问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问题排查首先确定内存泄漏问题出现的时间,发现在该时间点的上...
    99+
    2023-06-16
  • C++之内存泄漏排查详解
    目录一 、经验排查二 、使用Visual Leak Detector for Visual C++2.1 Visual Leak Detector for Visual C++简介2...
    99+
    2024-04-02
  • Java内存泄漏实例排查分析
    这篇文章主要介绍“Java内存泄漏实例排查分析”,在日常操作中,相信很多人在Java内存泄漏实例排查分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java内存泄漏实例排查分析”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-16
  • drawimage内存泄漏问题怎么解决
    解决drawImage内存泄漏问题的方法如下:1. 及时释放资源:使用完image对象后,可以调用`image = null;`来手...
    99+
    2023-09-05
    drawimage
  • C++内存泄漏问题分析与解决方案
    C++内存泄漏问题分析与解决方案在C++的开发过程中,内存泄漏是一个常见的问题。当程序动态分配内存后却没有正确释放,在程序运行过程中会导致内存的不断累积,最终耗尽系统的可用内存。内存泄漏不仅会影响程序的性能,还可能导致程序崩溃甚至系统崩溃。...
    99+
    2023-10-22
    C++ 解决方案 内存泄漏
  • java堆外内存泄漏如何排查
    在Java中,堆外内存泄漏通常是由于未正确释放使用了堆外内存的资源所导致的。下面是一些排查堆外内存泄漏的常见方法:1. 使用JVM工...
    99+
    2023-08-24
    java
  • java堆外内存泄漏怎么排查
    在Java中,堆外内存通常是通过直接内存(Direct Memory)分配的。直接内存是一种不受Java堆内存管理的内存分配方式,它...
    99+
    2023-10-27
    java
  • GoLang内存泄漏原因排查详解
    目录背景临时性内存泄漏通道理解背景 Go 语言中有对应的Go 内存回收机制,在Go采用 并发三色标记清除  算法, 但是由于实际的过程中 发现会有一些内存泄漏的常见,内存泄...
    99+
    2022-12-15
    GoLang内存泄漏 Go内存泄漏
  • Node如何排查内存泄漏
    这篇文章主要讲解了“Node如何排查内存泄漏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Node如何排查内存泄漏”吧!在 Nodejs 服务端开发的场景中,内存泄漏 绝对是最令人头疼的问题...
    99+
    2023-07-05
  • 怎么排查Javascript内存泄漏
    这篇文章主要讲解了“怎么排查Javascript内存泄漏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么排查Javascript内存泄漏”吧!如何判断我的应用发生了内存泄漏为了证明螃蟹的听...
    99+
    2023-07-02
  • Java内存泄漏排查的示例分析
    这篇文章将为大家详细讲解有关Java内存泄漏排查的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在一个凄凉的午夜午夜刚过,我就被一条来自监控系统的警报吵醒了。Adventory,我们的 PPC (...
    99+
    2023-06-04
  • golang内存泄漏怎么排查
    在 Go 语言中,内存泄漏通常是由于不正确地使用或管理指针和引用导致的。以下是一些排查内存泄漏的常用方法:1. 使用 go buil...
    99+
    2023-10-21
    golang
  • linux内存泄漏怎么排查
    要排查Linux中的内存泄漏,可以采取以下步骤: 监视和跟踪内存使用:使用工具如top、htop、vmstat等监视系统的内存使...
    99+
    2024-02-29
    linux
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作