Java 强引用

定义

强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器宁愿抛出OOM(OutOfMemoryError)也不会回收它。

说明

不要被这个强字吓到,以为这个引用就很厉害,其实强引用就是程序中使用的一般引用类型。举个简单的栗子:

String s = new String("Hello Frank!");

强可达 如果一个对象与GC Roots之间存在强引用,则称这个对象为强可达(strong reachable)对象。

关于可达性如果不太清楚的话,可以翻阅这篇文章

当你声明一个变量并指向一个实例的时候,其实就是在创造一个强引用。那么,既然叫强引用,它“强”在哪里呢?

这主要体现在JVM进行GC的时候,只要对象有强引用与其关联,就绝对不会对它进行回收,即使已经内存不足了也不会收回有强引用指向的对象。

如果你不需要使用某个对象了,可以将相应的引用设置为null,消除强引用来帮助垃圾回收器进行回收。因为过多的强引用也是导致OOM的罪魁祸首。

s = null;

显式地设置消除引用,或已超出对象的生命周期范围,则JVM会认为该对象不存在引用,这时就可能会回收这个对象。但是具体什么时候收集这要取决于具体的GC算法。

如果在一个方法的内部有一个变量s持有一个对象(Object)的强引用,那么这个变量s保存在栈中,而真正的引用内容(object)保存在堆中。当这个方法运行完成后就会退出方法栈,则引用s也会被销毁,这个object就会被回收。但是当这个s是全局变量时,就需要在不再使用这个对象时赋值为null,因为有强引用关联的对象是不会被垃圾回收的。

下面看另一个?:

A a = new A();
B b = new B(a);
a = null;

这里a和b是强引用,当把 a = null 时,这时 a 不再指向 A 的地址。讲道理:当某个对象不再与其他引用关联时,就会被 垃圾回收器判定为可回收,在GC中就会被回收掉。但是这里a = null 时,A 对象不能被回收,因为还有一个B对象持有其强引用,这时候就造成了内存泄漏

再看另一个会导致内存泄漏的栗子:

public static ArrayList<Object> list = new ArrayList<Object>();
public void stackOverflowTest(Object object){
    list.add(object);
    object = null;
}

GC回收的是不可达、弱可达或者虚可达对象,但是,在这个静态集合类对象中,持有了对象的强引用,但是却有可能对象已经不再使用了,所以当非静态对象被静态变量持有强引用的时候,最容易发生内存泄露,在方法中从list获取到对象后赋值给一个变量,使用完之后将这个变量设置为null并不会释放object引用的对象,因为list中还是持有对象的强引用。这时就造成了内存泄漏

小结

所以小结一下强引用的特点:

  • 强引用就是最普通的引用
  • 可以使用强引用直接访问目标对象
  • 强引用指向的对象在任何时候都不会被系统回收
  • 强引用可能会导致内存泄漏
  • 过多的强引用会导致OOM

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Vamei实验室

Python深入06 Python的内存管理

语言的内存管理是语言设计的一个重要方面。它是决定语言性能的重要因素。无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征。这里以Python语...

3329
来自专栏谦谦君子修罗刀

swift4.0语法杂记(精简版)

一、swift简史 1、介绍 swift是苹果公司于2014年推出用于撰写OS和iOS应用程序的语言。它由苹果开发者工具部门总监“克里斯.拉特纳”在2010年...

4379
来自专栏Web 开发

JavaScript的对象引用

在一个函数体内,var变量声明的变量,其作用域只在该函数体内,对于函数体外而言,是不可见的(废话)。

810
来自专栏数据结构与算法

病毒

【问题描述】   有一天,小y突然发现自己的计算机感染了一种病毒!还好,小y发现这种病毒很弱,只是会把文档中的所有字母替换成其它字母,但并不改变顺序,也不会增加...

5197
来自专栏我是攻城师

再谈方法调用与堆栈

堆内存是被多个线程共享的,而栈内存是线程私有的。堆主要用来存储运行时所有的对象数据和各种数组,简单点说通过new创建的实例,都会在堆上分配空间。堆在虚拟机启动时...

961
来自专栏逸鹏说道

Python3 与 C# 基础语法对比(List、Tuple、Dict专栏)

Python3 与 C# 基础语法对比(基础知识场):https://www.cnblogs.com/dotnetcrazy/p/9102030.html

873
来自专栏xx_Cc的学习总结专栏

iOS底层原理总结 - 探寻block的本质(二)

2834
来自专栏阿杜的世界

【转】Java知识点集锦(1~40)

答:不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primi...

1052
来自专栏绿巨人专栏

[Java] 设计模式: Code Shape - 管理你的代码结构

912
来自专栏云霄雨霁

Java--类和对象之初始化和清除

1835

扫码关注云+社区

领取腾讯云代金券