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 }
复制代码

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/6682968.html,如需转载请自行联系原作者

相关文章
|
6月前
|
缓存 Java API
JVM 四种引用和使用场景
在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)四种,Java 4种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用 > 虚引用。
61 0
|
开发框架 前端开发 Java
JVM学习笔记(二)------Java代码编译和执行的整个过程
JVM学习笔记(二)------Java代码编译和执行的整个过程
|
4月前
|
JSON Java BI
一次Java性能调优实践【代码+JVM 性能提升70%】
这是我第一次对系统进行调优,涉及代码和JVM层面的调优。如果你能看到最后的话,或许会对你日常的开发有帮助,可以避免像我一样,犯一些低级别的错误。本次调优的代码是埋点系统中的报表分析功能,小公司,开发结束后,没有Code Review环节,所以下面某些问题,也许在Code Review环节就可以避免。
158 0
一次Java性能调优实践【代码+JVM 性能提升70%】
|
6月前
|
存储 缓存 算法
深入浅出JVM(十四)之内存溢出、泄漏与引用
深入浅出JVM(十四)之内存溢出、泄漏与引用
|
6月前
|
存储 缓存 Java
JVM 引用
JVM中所有的引用类型,都是抽象类java.lang.ref.Reference的子类,这个类的主要方法为get()方法。
|
存储 缓存 算法
GC面临的困境,JVM是如何解决跨代引用的?
前面我们讲了可达性分析和根节点枚举,介绍完了GC的前置工作,下面开始讲GC的工作过程。
160 0
GC面临的困境,JVM是如何解决跨代引用的?
|
缓存 监控 前端开发
JVM学习日志(三) Java代码执行流程
简述 Java代码执行流程
103 0
JVM学习日志(三) Java代码执行流程
|
Oracle Java 关系型数据库
02-有哪些常见的JVM?请说下Java代码的运行机制
常见的JVM有Oracle JDK、OpenJDK、IBM JVM、Azul Zing JVM等。Java代码的运行机制如下:首先,Java源代码被编译成字节码文件(.class文件),其中包含了可执行指令。然后,JVM将字节码加载到内存中,进行校验、准备和解析等操作。接着,JVM将字节码转换为机器码,并交给处理器执行。执行过程中,JVM负责内存管理、垃圾回收和线程调度等任务。最后,程序执行完毕或遇到异常,JVM终止程序的运行。JVM的关键组件包括类加载器、即时编译器和垃圾回收器,它们确保了Java代码的可移植性、安全性和性能优化。这些信息有助于理解Java代码是如何在JVM上运行的。
113 0
02-有哪些常见的JVM?请说下Java代码的运行机制
|
存储 算法 Java
JVM 收集算法 垃圾收集器 元空间 引用
JVM 收集算法 垃圾收集器 元空间 引用
104 0
|
Arthas 监控 安全
浅谈阿里开源JVM Sandbox(内含代码实战)
浅谈阿里开源JVM Sandbox(内含代码实战)
47182 6
浅谈阿里开源JVM Sandbox(内含代码实战)