欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解JAVA 强引用

程序员文章站 2022-04-21 11:01:27
定义强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器宁愿抛出oom(outofmemoryerror)也不会回收它。说明不要被这个强字吓到,以为这个引用就很厉害,其实强引用就是程序中使用...

定义

强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器宁愿抛出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 *test(object object){
  list.add(object);
  object = null;
}

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

小结

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

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

以上就是详解java 强引用的详细内容,更多关于java 强引用的资料请关注其它相关文章!