Java中四种引用类型(强引用、软引用、弱引用、虚引用)
在Java中有四种引用类型:强引用、软引用、弱引用、虚引用
在谈论引用之前呢,首先我们要了解一下引用计数器
引用计数器
在 Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单 的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个对象如果没有任何与之关联的引用,即他们的引用计数都为 0,则说明对象不太可能再被用到,那么这个对象就是可回收对象。
特点:
- 每当有一个地方引用它时,计数器就加1,当引用失效时,计数器就减1;任何时刻计数器为0的对象就是不可能在被使用的.
- 默认标记次数 = 15次,当标记 = 0,gc直接回收对象被引用的话,就会 +1,然后放到 s0或者s1区(不了解得同学可以去看看垃圾回收机制),如果还是被频繁使用,那么会放入老年代中。
- 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不再被使用的,垃圾收集器将回收该对象使用的内存。
强引用
在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即 使该对象以后永远都不会被用到 JVM 也不会回收。因此强引用是造成 Java 内存泄漏的主要原因之 一。
public class Test {
@Override
protected void finalize() throws Throwable {
System.out.println("我是对象!我被回收啦!");
}
public static void main(String[] args) {
Test test=new Test();
System.gc();
}
}
//输出为空,此时test对象的引用变量为强引用
软引用
软引用用来描述一些还有用,但非必须的对象。对于软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。
软引用需要用 SoftReference 类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。
public class Test {
@Override
protected void finalize() throws Throwable {
System.out.println("我是对象!我被回收啦!");
}
public static void main(String[] args) {
Test test=new Test();
SoftReference softReference=new SoftReference(test);
}
}
//此时内存足够,new出来的Test对象为软引用,不会被回收
//输出为空
public class Test {
@Override
protected void finalize() throws Throwable {
System.out.println("我是对象!我被回收啦!");
}
public static void main(String[] args) {
int i=0;
Test test;
while (true) {
test = new Test();
SoftReference softReference = new SoftReference(test);
}
}
}
//当创建对象过多使内存不足时,之前创建的对象就为空
//输出:循环一直输出"我是对象!我被回收啦!"
弱引用
弱引用用来描述非必须对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
弱引用需要用 WeakReference 类来实现,它比软引用的生存期更短,对于只有弱引用的对象 来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,总会回收该对象占用的内存。
public class Test {
@Override
protected void finalize() throws Throwable {
System.out.println("我是对象!我被回收啦!");
}
public static void main(String[] args) {
int i=0;
WeakReference weakReference=new WeakReference(new Test());
System.gc();
}
}
//不管内存是否充足,只要gc一旦运行,对象总会被回收
//输出"我是对象!我被回收啦!"
虚引用
虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其是生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是希望能在这个对象被收集器回收时收到一个系统通知。
虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用。虚 引用的主要作用是跟踪对象被垃圾回收的状态。