Java内存泄漏发生的情况

Java 中发生内存泄漏 5 个场景以及解决方法 前言 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和 Java 联系起来。在 Java 中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM 来处理。顾名思义,垃圾回收就是释放垃圾占用的空间,但垃圾回收器并不是万能的,它能够处理大部分场景下的内存清理、内存泄露以及内存优化。但它也并不是万能的,不然我们在项目实践过程中也不会出现那么多的内存泄漏的问题,很多的内存泄漏都是因为开发人员操作不当导致的。 本篇文章我们就来聊聊内存泄露的原因是什么,以及如何在 阅读详情

虽然Java自带垃圾回收机制(GC),程序员不需要手动进行内存管理,但是仍然会出现内存泄漏的情况。尽管如此,Java的自动内存管理,比起C/C++,内存泄漏的情况大大减少了。下面总结下什么情况下会发生Java内存泄漏。

静态集合类

在使用Set、Vector、HashMap等集合类的时候需要特别注意,有可能会发生内存泄漏。当这些集合被定义成静态的时候,由于它们的生命周期跟应用程序一样长,这时候,就有可能会发生内存泄漏,看下面代码:

class StaticTest
{
    private static Vector v = new Vector(10);

    public void init()
    {
        for (int i = 1; i < 100; i++)
        {
            Object object = new Object();
            v.add(object);
            object = null;
        }
    }
}

在上面的代码中,循环申请了Object对象,并添加到Vector中,然后将对象设置为null,可是这些对象因为被Vector引用着,因此并不能被GC回收,因此造成了内存泄漏。因此,要释放这些对象,还需要被它们从Vector删除,最简单的方法就是将Vector设置为null。

集合里的对象属性值被改变

看以下代码:

public static void main(String[] args)
{
    Set<Student> set = new HashSet<Student>();
    Student s1 = new Student("Jack");
    Student s2 = new Student("Mary");
    Student s3 = new Student("Eason");

    set.add(s1);
    set.add(s2);
    set.add(s3);

    System.out.println(set.size());//3
    s2.setName("Jackson"); //修改属性,此时s2元素对应的hashcode值发生改变
    set.remove(s2);        // remove不掉,造成内存泄漏
    set.add(s2);           // 添加成功

    System.out.println(set.size());//4
}

在这个例子中,由于对象s2的属性值被改变了,因此不能从set中删除,所以set中会一直保持着s2的引用,不能被回收,造成了内存泄漏。

监听器

在Java中,我们经常会使用到监听器,如对某个控件添加单击监听器addOnClickListener(),但往往释放对象的时候会忘记删除监听器,这就有可能造成内存泄漏。好的方法就是,在释放对象的时候,应该记住释放所有监听器,这就能避免了因为监听器而导致的内存泄漏。

各种连接

Java中的连接包括数据库连接、网络连接和io连接,如果没有显式调用其close()方法,是不会自动关闭的,这些连接就不能被GC回收而导致内存泄漏。一般情况下,在try代码块里创建连接,在finally里释放连接,就能够避免此类内存泄漏。

外部模块的引用

调用外部模块的时候,也应该注意防止内存泄漏。如模块A调用了外部模块B的一个方法,如:
public void register(Object o)
这个方法有可能就使得A模块持有传入对象的引用,这时候需要查看B模块是否提供了去除引用的方法,如unregister()。这种情况容易忽略,而且发生了内存泄漏的话,比较难察觉,应该在编写代码过程中就应该注意此类问题。

单例模式

使用单例模式的时候也有可能导致内存泄漏。因为单例对象初始化后将在JVM的整个生命周期内存在,如果它持有一个外部对象(生命周期比较短)的引用,那么这个外部对象就不能被回收,而导致内存泄漏。如果这个外部对象还持有其它对象的引用,那么内存泄漏会更严重,因此需要特别注意此类情况。这种情况就需要考虑下单例模式的设计会不会有问题,应该怎样保证不会产生内存泄漏问题。

参考



文/zhutoulwz(简书作者)
原文链接:http://www.jianshu.com/p/93b91ea18c28
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。


=================================================补充====================================================

集合里的对象属性值被改变,这里的demo代码解释的有问题,hashset中的对象,修改了之后,会remove成功。对象存放的位置是不会发生变化的。我用jdk1.7跑过。

c6942557eef2: @c6942557eef2 在student没有重载hashCode函数的情况下是这样的



小心,用String写代码可能会内存泄漏 今天给大家聊聊平时写代码的时候最常见的String字符串代码它的一些底层原理,以及使用不当可能引发的内存泄漏的问题,相信对于大家平时日常开发写代码会有一定的帮助。 阅读详情

相关推荐

《effective java》第6条:消除过期的对象引用,Java内存泄漏发生的情况

泄露的三个常见来源: 1 过期引用 2 缓存(缓存应该时不时的清除掉没用的项) 3监听器和其他回调 -----实例----- 1 静态集合类,虽然引用重新指向null,但是集合中的该元素依然指向原对象,原对象并没有被改变。 private static List list = new ArrayList(10); private static Object[] ar...

Top5软件工程硕士,先后在京东、字节从事多年Java后端开发、实时和离线大数据开发 472

JAVA系列---内存泄露示例

这绝大概率就是内存泄漏了啊。但是在生产上的内存走势图完全看不出来这个趋势,我前面说了,主要因为 GC 情况的数据只会保留一周时间,所以就算把整个图放出来也不是那么直观。我再带着你看看另外一个视角,这是我真正定位到问题的视角。就是分析内存 Dump 文件。分析内存 Dump 文件的工具以及相关的文章非常的多,我就不赘述了,你随便找个工具玩一玩就行。我这里主要是分享一个思路,所以就直接使用 idea 里面的 Profiler 插件了,方便。

lipviolet的博客 1308

详解Java内存泄露的示例代码

通过一个Demo来简要介绍下ThreadLocal和ClassLoader导致内存泄露最终OutOfMemory的场景。下面通过示例代码给大家分享Java内存泄露的相关知识,感兴趣的朋友一起看看吧

java中内存泄露8种情况的总结

由于java的JVM引入了垃圾回收机制,垃圾回收器会自动回收不再使用的对象,了解JVM回收机制的都知道JVM是使用引用计数法和可达性分析算法来判断对象是否是不再使用的对象,本质都是判断一个对象是否还被引用。那么对于这种情况下,由于代码的实现不同就会出现很多种内存泄漏问题(让JVM误以为此对象还在引用中,无法回收,造成内存泄漏)。本文将解析常见8种内存泄露的情况

ratel的博客 7万+

vivado下ECO操作-不重新综合实现修改属性并生成.bit

ECO即engineer change order,即工程变更指令,可以对设计做局部小改动并只对改动部分重新布局布线并生成.bit。在一个工程动辄编译几个小时情况下,可以在调试中节省大量时间。比如我们在调试中,需要改变时钟占空比或者相位,需要改变寄存器初值等等,此时用ECO暂时改动,待验证后在重新编译无疑是最有效率的方法。 实现ECO通常有两种方式,一是通过vivado界面完成,另一种方法就是tcl脚本。所有的ECO操作都可以通过tcl操作完成,有的操作用vivado界面无法完成,只能通过tcl。以下主要

4657

Transformer模型详解(图解最完整版)

Transformer由论文提出,现在是谷歌云TPU推荐的参考模型。论文相关的Tensorflow的代码可以从GitHub获取,其作为Tensor2Tensor包的一部分。哈佛的NLP团队也实现了一个基于PyTorch的版本,并注释该论文。在本文中,我们将试图把模型简化一点,并逐一介绍里面的核心概念,希望让普通读者也能轻易理解。Transformer 与 RNN 不同,可以比较好地并行训练。

2501_91695094的博客 2700

Java发生内存泄漏的情况

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34391854的博客 111

Kindle使用USB数据线传书封面无法显示问题

不建议按这个解决封面问题,首先USB多次插拔麻烦,其次就是我起初按博主方法没啥问题,后面无论我怎么个顺序都出现了‘暂无图片’,我的建议是在亚马逊退出国内只能USB传书的情况下,下载一个calibre 和。飞行模式下用calibre传书到kindle ,然后用Fix Kindle Ebook Cover 修复一下,后面你要继续飞行模式还是连网随你便,两步完事。2,‘’发送到设备’的时候也最好选择 ‘发送特定格式至’ 选择具体的电子书格式,你的电子书是azw3就选azw3,是mobi就选mobi。

meser88的博客 7416

java中是否存在内存泄漏?什么情况下才是内存泄漏?

JAVA中的内存泄漏 Java中的内存泄露,就是:不再会被使用的对象的内存不能被回收,就是内存泄露。也可以说一个不再被程序使用的对象或变量一直被占据在内存中。 Java中的内存管理 Java中的内存管理是垃圾收集器(GC)的责任。 在应用程序运行时,应用程序会创建大量对象,每个对象都有它的生命周期。在内存中,其他对象引用的对象称为活动对象。任何活动对象不再引用的对象都被视为死对象,称为垃圾。查找和...

ZYM5200的博客 586

【S32K】S32K144入门笔记(3) SPI(lpspi组件)

0. 引言 与第二篇can对应,第三篇本来想写lin的,毕竟都是车身上常用的总线。但是lin比较麻烦,所以先拖后一下,先把SPI记录一下。 SPI在我们的系统架构中是S32K和ADAS之间做数据传输用的,毕竟速率够高,数据量能传的比较大。 1. 准备 1.1 SPI基础知识 1.2 开发环境 1.2.1 软件开发环境 1.2.2 硬件环境 SPI 2. Demo ...

YoYo的桃子树 2万+

树莓派5安装ROS2小白指南避坑攻略

手把手教你如何在树莓派5上顺利安装ROS2,避开常见问题与陷阱,提升配置效率。针对树莓派5安装ros2过程中的依赖冲突、源配置错误等高频难题提供解决方案,适合新手快速上手。

weixin_35754962的博客 1004

Java内存泄漏介绍

内存管理是Java最重要的优势之一,你只需创建对象,Java垃圾收集器会自动负责分配和释放内存。但是,情况并不那么简单,因为在Java应用程序中经常发生内存泄漏。 本章会说明什么是内存泄漏,为什么发生,以及如何防止它们。 什么是内存泄漏? 内存泄漏的定义:应用程序不再使用的对象,垃圾收集器却无法删除它们,因为它们正在被引用。 为了理解这个定义,我们需要了解对象在内存中的状态。下图说明了什么是未引用的,什么是引用的对象。 从图中可以看出,有被引用的对象和未被引用的对象。未引用的对象将被垃圾收集,而被引用的对

Java技术栈,分享最主流的Java技术 452

基于Multisim/TINA的H桥电机驱动电路设计与仿真分析

摘要 本文基于Multisim/TINA仿真平台,对H桥电机驱动电路进行了系统设计与分析。研究重点包括H桥拓扑结构的工作原理、PWM调速控制方法以及两种驱动方案对比分析。通过光耦隔离驱动与IR2110专用驱动IC的仿真对比,验证了IR2110自举电路在高低侧驱动中的优势。仿真实验着重分析了死区时间对防止直通现象的关键作用,并建立了直流电机的R-L-E等效模型进行动态特性仿真。结果表明,采用IR2110驱动方案配合适当的栅极电阻和自举电容参数,能够实现电机的高效双向调速控制。本研究为实际电机驱动系统的设计提供

huanghm88的专栏 137

面试官:如何处理内存泄漏问题?我:内存泄漏是什么?

当程序未能释放未使用的资源(例如对象、数据库连接或文件句柄)时会发生内存泄漏,而当一个对象保留对另一个对象的引用时会发生引用泄漏,即使后者不再需要。这些非预期的对象引用会阻止内置的 Java 垃圾收集进程清除这些对象获取的内存。在本文中,我们研究了内存泄漏是什么、为什么会发生以及如何防止 Java 中的内存泄漏。

无休居士的博客 1040

【人工智能】AI驱动值班巡检Agent(Hermes)

传统运维值班巡检场景中,存在四大核心痛点:本项目基于 Agent+Skills+浏览器自动化 架构,构建了具备自我进化能力的AI值班员,核心逻辑流如下:

奶爸的编程之路,也就一周冷个三天 178

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

.内存泄漏与操作系统原理

内存泄漏大家都知道这个名字,具体原理鲜有教科书说明。现在我结合一点理论知识阐明一下这个问题,大家有玉的尽管砸过来啊! 1,引发问题的时间?    显然不运行的程序是不可能使用内存的,内存泄漏一定发生在该程序运行时刻。 2,发生内存泄漏的对象?

zj0910 1110

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java的内存泄漏

       Java的一个重要优点就是通过垃圾收集器(Garbage Collection,GC)自动管理内存的回收,程序员不需要通过调用函数来释放内存。因此,很多程序员认为Java不存在内存泄漏问题,或者认为即使有内存泄漏也不是程序的责任,而是GC或JVM的问题。其实,这种想法是不正确的,因为Java也存在内存泄露,但它的表现与C++不同。 问题的提出       Java的一个重

blue_fire2007的专栏 414

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

JAVA内存泄漏

JAVA内存泄漏介绍java内存泄漏的概念 线上遇到内存泄漏的解决方案1.概念如果内存空间中存在某些对象 ,拥有这两种特点,就可以判断为Java中的内存泄漏1.对象无用 2.无用的对象还被引用着简单来说就是无用的内存不能被回收,就是内存泄露,长时间的内存泄漏会导致内存空间不够,最终导致OOM。2.发生原因对象都是有生命周期,有的长,有的短,长生命周期的对象A引用短生命周期的对象B,当对象B没有被程序

森林里的一天 381

Java的内存泄漏(一)

举例不清,请阅读内存泄漏(二)

逆风飞扬的专栏 675

java中是否存在内存泄漏?什么情况下才是内存泄漏

当Float对象在第二行被创建时,什么时候能被垃圾回收站回收? 1.public Object m(){ 2. Object o = new Float(3.14F); //o----------> new Float(3.14f) 3. Object[] oa = new Object[1]; 4. oa[0] = o; // o----------&gt...

J______J的博客 606

Java内存泄漏

Java内存泄漏 所为内存泄漏,就是指一个不被程序使用的对象一直占用在内存中。Java有垃圾回收机制,它可以保证当一个对象不再被使用时,对象自动被垃圾回收器从内存中回收掉。由于Java是采用有向图的方式进行垃圾回收管理,可以消除引用循环的问题。例如当两个对象相互引用时,只要他们与根不可达,那么就可以将他们回收掉。 Java 中的内存泄露的情况:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是 Java

cxh9662的博客 128
上一篇: 在 JNI 编程中避免内存泄漏
下一篇: Java_字符编码(Unicode、UTF-8、UTF-16)
hookfeng
博客等级 码龄12年 4粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值