我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java内存泄漏知识(软引用、弱引用等)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java内存泄漏知识(软引用、弱引用等)

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。
未经允许不得转载

目录

ddd

一、导读

我们继续总结学习Java基础知识,温故知新。

二、概览

要学习内存泄漏,我们要知道一些基础知识,如Java引用分类:

2.1 强引用

平时常用的引用类型,JVM发生OOM也不会回收这部分引用。
如果强引用对象不使用时,需要弱化从而使GC能够回收,如 object = null;

2.2 软引用(SoftReference)

发生OOM前(jvm内存不足时)会回收这部分引用,如果想使用缓存,可以使用 LruCache,而不是SoftReference
如果一个对象只具有软引用,则内存空间充足时,垃圾回收器就不会回收它;
如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。

    if(JVM内存不足) {        // 将软引用中的对象引用置为null        str = null;        // 通知垃圾回收器进行回收        System.gc();    }

2.3 弱引用(WeakReference)

发生GC就会回收
一旦开始gc,只要发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存

我们一起来看看构造方法

public WeakReference(T referent) {    super(referent);}public WeakReference(T referent, ReferenceQueue<? super T> q) {    super(referent, q);}

假设我们以后对象存储在一个列表,比如HashMap中,我们想要真正的回收一个对象,仅仅把它的强引用赋值为null是不够的,还要把相应的条目从HashMap中移除。

2.4 虚引用(PhantomReference)

get方法返回null,不能获取值。

在这里插入图片描述

三、相关知识

内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
内存泄漏缺陷具有隐蔽性、积累性的特征,比其他内存非法访问错误更难检测。

3.1 内存泄露危害

  • 当应用程序长时间连续运行时,性能严重下降;
  • 抛出OutOfMemoryError异常;
  • 程序莫名其妙的自动崩溃;
  • 应用程序耗尽链接对象。
  • 等等

3.2 列举实际开发中遇到的内存泄露场景

  • 非静态内部类的静态实例

  • 单例造成的内存泄漏
    如果一个对象已经不再需要使用了,而单例对象还持有该对象的引用,就会使得该对象不能被正常回收,从而导致了内存泄漏。

  • 非静态内部类创建静态实例造成的内存泄漏
    eg: Handler造成的内存泄漏
    原因:在类中将 Handler 声明成非静态内部类或者匿名内部类,这样Handle默认持有外部类Activity的引用,如果Activity在销毁时,
    Handler还有未执行完或者正在执行的Message,而Handler又持有Activity的引用,导致GC无法回收Activity,导致内存泄漏

解决方法: 将Handler类独立出来或者使用静态内部类 + 弱引用,这样便可以避免内存泄漏。 内部类改为静态的之后,
它所引用的对象或属性也必须是静态的,所以静态内部类无法获得外部对象的引用,只能从 JVM 的 Method Area(方法区)获取到static类型的引用

问题:内部类为什么会持有外部类的引用

内部类虽然和外部类写在同一个文件中,但是编译后还是会生成不同的class文件,其中内部类的构造函数中会传入外部类的实例,内部类持有外部类的对象的引用,是以“this$0”这个字段来保存的

Java 语言中,非静态内部类的主要作用有两个:

1. 当内部类只在外部类中使用时,匿名内部类可以让外部不知道它的存在,从而减少了代码的维护工作。2. 当内部类持有外部类时,它就可以直接使用外部类中的变量了,这样可以很方便的完成调用,
  • 线程造成的内存泄漏
    ThreadLocal 造成的内存泄漏,ThreadLocal会复制变量副本,

解决方法: 将AsyncTask和Runnable类独立出来或者使用静态内部类,这样便可以避免内存泄漏。

匿名内部类/非静态内部类和异步线程。

  • 资源未关闭造成的内存泄漏
    对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,从而造成内存泄漏。 资源型对象未关闭: Cursor,File

  • 类的静态变量持有大数据对象(static 字段)

  • 集合容器中的对象没清理造成的内存泄漏

  • finalize()
    重写finalize()方法时,该类的对象不会立即被垃圾收集器收集,如果finalize()方法的代码有问题,那么会潜在的引发OOM;

  • 注册对象未销毁: 广播,回调监听

  • WebView: 使用单独进程

3.3 软引用 & 弱引用区别

  • 弱引用的对象拥有更短暂的生命周期
  • 回收的时机不同

四、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

未经允许不得转载

在这里插入图片描述

来源地址:https://blog.csdn.net/fumeidonga/article/details/132214403

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java内存泄漏知识(软引用、弱引用等)

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

下载Word文档

猜你喜欢

Java中怎么用弱引用堵住内存泄漏

本篇内容主要讲解“Java中怎么用弱引用堵住内存泄漏”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中怎么用弱引用堵住内存泄漏”吧!虽然用 Java™ 语言编写的程序在理论上是不会出现“内
2023-06-03

解决NSTimer循环引用导致内存泄漏的六种方法

解决NSTimer循环引用导致内存泄漏的六种方法如下:1. 使用weak引用:在创建NSTimer时使用weak引用来引用目标对象,可以避免循环引用。例如,可以使用weak引用指向目标对象,并且在NSTimer的回调方法中使用strong引
2023-09-20

如何用Java编写一段代码引发内存泄露

今天就跟大家聊聊有关如何用Java编写一段代码引发内存泄露,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Q:刚才我参加了面试,面试官问我如何写出会发生内存泄露的Java代码。这个问题
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录