JVM中强引用,弱引用,软引用和幽灵引用的代码

 上代码: 

  1 public class ReferenceTest {
  2     public static void main(String[] args) {
  3         //test1();//软引用
  4         //test2();//弱引用
  5         //test3();//幽灵引用_1
  6         test4();//幽灵引用_2
  7         
  8     }
  9     public static void test1(){
 10         //在堆中创建一个对象Obj
 11         //在栈中创建一个p来强引用此对象Obj
 12         Person p=new Person(1);
 13         
 14         //在栈中创建一个softReference来软引用此对象Obj 可以获取对象的属性值
 15         SoftReference<Person> softReference=new SoftReference<Person>(p);
 16         System.out.println(p.getId());//输出打印:1
 17         System.out.println(softReference.get().getId());//输出打印:1
 18         
 19         //断开p和Obj的强引用
 20         p=null;
 21         //System.out.println(p.getId());    
 22         //System.gc();
 23         System.out.println(softReference.get().getId());//输出打印:1 
 24         //并不报空指针异常  虽然断开了p和Obj的强引用,但是并没有被回收.
 25         //如果在前面调用gc() 垃圾回收  运行结果也是打印1的..软引用只有系统在发生内存溢出异常之前,会把只被软引用的对象进行回收
 26     }
 27 
 28     public static void test2(){
 29         //在堆中创建一个对象Obj
 30         //在栈中创建一个p来强引用此对象Obj
 31         Person p=new Person(1);
 32         
 33         //在栈中创建一个weakReference来弱引用此对象Obj 可以获取对象的属性值
 34         WeakReference<Person>  weakReference=new WeakReference<Person>(p);
 35         System.out.println(weakReference.get().getId());//打印输出:1
 36         
 37         //断开p和Obj的强引用
 38         p=null;
 39         //System.gc();
 40         System.out.println(weakReference.get().getId());//打印输出:1 
 41         //p=null 之后 还是可以正常的打印输出1  说明断开强引用和其他弱引用,软引用压根没有关系.
 42         //如果在打印之前 调用gc() 方法之后  就会报错..java.lang.NullPointerException
 43         //垃圾回收不论内存是否不足都会回收只被弱引用关联的对象。
 44         
 45     }
 46     
 47     public static void test3(){
 48         //在堆中创建一个对象Obj
 49         //在栈中创建一个p来强引用此对象Obj
 50         Person p=new Person(1);
 51         
 52         //Phantom 幻影幽灵 的意思
 53         ReferenceQueue<Person> referenceQueue = new ReferenceQueue<Person>();
 54         //在栈中创建一个phantomReference来虚引用此对象Obj 不可以获取对象的属性值
 55         PhantomReference<Person> phantomReference=new PhantomReference<Person>(p,referenceQueue);
 56         System.out.println(phantomReference.get().getId());//打印报错 java.lang.NullPointerException
 57         //直接得不到p对象对应的id值....
 58         //PhantomReference的唯一作用就是 能在这个对象被收集器回收时收到一个系统通知 看test4()方法
 59     }
 60     
 61     public static void test4(){
 62         
 63         //在堆中创建一个对象Obj
 64         //在栈中创建一个p来强引用此对象Obj
 65         Person p=new Person(1);
 66         
 67         //Phantom 幻影幽灵 的意思
 68         ReferenceQueue<Person> referenceQueue = new ReferenceQueue<Person>();
 69         //在栈中创建一个phantomReference来虚引用此对象Obj 不可以获取对象的属性值
 70         PhantomReference<Person> phantomReference=new PhantomReference<Person>(p,referenceQueue);
 71         
 72         System.out.println(referenceQueue.poll());//打印输出: null  这个是查询队列中是否有元素.
 73         
 74         //断开p和obj的强引用
 75         p=null;
 76         System.gc();//p被回收之后 队列referenceQueue中就有值了.
 77         
 78         try {
 79             Thread.sleep(1000);
 80         } catch (InterruptedException e) {
 81             e.printStackTrace();
 82         }//过 一秒钟之后再查询队列中是否有元素.
 83         System.out.println(referenceQueue.poll());//打印输出: java.lang.ref.PhantomReference@77fef1a0
 84         //PhantomReference的唯一作用就是 能在这个对象被收集器回收时收到一个系统通知 
 85         //如果这个对象被回收了,会把通知放到队列中.
 86         
 87         //如果前面p=null注释掉  再运行打印输出就是  null  因为p没有被回收(强引用中) 就不会把通知放到队列中...队列中为空 null
 88         //回收的标志就是把通知放到队列中..
 89     }
 90 }
 91 
 92 class Person{
 93     public Person(Integer id) {
 94         this.id = id;
 95     }
 96 
 97     private Integer id;
 98 
 99     public Integer getId() {
100         return id;
101     }
102 
103     public void setId(Integer id) {
104         this.id = id;
105     }
106 
107     @Override
108     protected void finalize() throws Throwable {
109         System.out.println("finalized!!!!!");
110     }
111 }
原文地址:https://www.cnblogs.com/DreamDrive/p/6682968.html