JAVA引用Reference总结

1.JAVA引用有四种

强引用  就是我们最常用的对象引用  String s = new String("");

SoftReference,

WeakReference

PhantomReference

FinalReference

2.先说说GC

2.1 先定义一个普通类  override finalliz 方法 

finalize()函数是在JVM回收内存时执行的,但JVM并不保证在回收内存时一定会调用finalize()

public class NormalClass {

@Override

    protected void finalize()throws Throwable {

super.finalize();

System.out.println("finalize gc is done");

}

}

2.2 写一个模拟内存内存溢出的类 

public class OOM {

public OOM() {

}

public static void oom(){

String name ="hello";

for (int i =0; i <100000000; i++) {

name += name;

}

System.out.println(name);

}

}

3  测试类

  第一种情况 清除对象 设置为null

public static void main(String[] args){

NormalClass normalClass =new NormalClass();

normalClass =null;

}

没有任何输出 

原因 jvm gc 没有触发 我们知道gc是jvm自己控制的 

第二种情况  System.gc()手工触发

public static void main(String[] args){

NormalClass normalClass =new NormalClass();

normalClass =null;

System.gc();

}

finalize gc is done

第三种情况  大量内存使用触发

public static void main(String[] args){

NormalClass normalClass =new NormalClass();

normalClass =null;

OOM.oom();

}

finalize gc is done

虽然我们没有手工触发,但是由于大量内存使用 导致jvm自己触发了GC


3 强引用

  所谓的强引用就是我们最常用的对象引用  

强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

我们用测试案例来理解这句话

public static void main(String[] args){

NormalClass normalClass =new NormalClass();

//normalClass = null;

    OOM.oom();

}

gc 没有执行 finalize gc is done 没有输出

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

NormalClass对象的引用还在 并没有被置空 

4 SoftReference

如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

    软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

我们用案例理解

public static void main(String[] args){

SoftReference ref =new SoftReference(new NormalClass()) ;

OOM.oom();

}

输出finalize gc is done

java.lang.OutOfMemoryError: Java heap space

public static void main(String[] args){

SoftReference ref =new SoftReference(new NormalClass()) ;

System.gc();

//OOM.oom();

}

输出 没有任何输出

内存够用 即使调用System.gc()  也没有被回收

5 WeakReference

 弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

    弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

案例

public static void main(String[] args){

WeakReference ref =new WeakReference(new NormalClass()) ;

OOM.oom();

}

输出 finalize gc is done

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

public static void main(String[] args){

WeakReference ref =new WeakReference(new NormalClass()) ;

//OOM.oom();

    System.gc();

}

输出 finalize gc is done 

WeakReference 意思就是只有gc动作 WeakReference就顺带回收了 

你可能感兴趣的:(JAVA引用Reference总结)