详解JAVA 强引用

作者:弗兰克的猫 时间:2021-11-06 18:38:16 

定义

强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器宁愿抛出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

来源:https://cloud.tencent.com/developer/article/1354162

标签:Java,引用,强引用
0
投稿

猜你喜欢

  • Flutter 使用fluro的转场动画进行页面切换

    2023-06-17 11:49:26
  • 剖析SpringCloud Feign中所隐藏的坑

    2023-11-19 05:32:03
  • Hibernate环境搭建与配置方法(Hello world配置文件版)

    2022-07-31 06:26:04
  • java控制台打印本月的日历

    2023-10-15 22:58:12
  • Android中通过RxJava进行响应式程序设计的入门指南

    2023-06-27 08:17:46
  • java线程之join方法的使用介绍

    2023-01-15 12:18:40
  • Java中初始化List集合的八种方式汇总

    2021-09-20 22:31:54
  • Java8特性使用Function代替分支语句

    2021-09-05 07:29:09
  • Java对zip,rar,7z文件带密码解压实例详解

    2023-11-29 05:08:32
  • 详解Java中对象池的介绍与使用

    2023-07-25 13:13:48
  • java 中HashCode重复的可能性

    2021-09-13 17:38:05
  • Java基础教程之String深度分析

    2022-08-19 05:42:15
  • java swing实现QQ账号密码输入框

    2023-01-13 06:26:52
  • java跟踪执行的sql语句示例分享

    2022-07-30 20:13:18
  • java模拟TCP通信实现客户端上传文件到服务器端

    2023-11-26 10:14:49
  • springboot读取配置文件中的参数具体步骤

    2023-11-29 05:46:14
  • SpringBoot和Swagger结合提高API开发效率

    2023-11-25 01:23:16
  • springmvc 分页查询的简单实现示例代码

    2022-01-09 11:08:22
  • Maven工程打包jar的多种方式

    2022-12-15 06:54:46
  • Spring-boot 2.3.x源码基于Gradle编译过程详解

    2022-04-07 15:41:36
  • asp之家 软件编程 m.aspxhome.com