- 浏览: 56042 次
- 性别:
- 来自: 杭州
最新评论
import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.concurrent.TimeUnit; public class ReferenceTest { /* * SoftReference SoftReference 在“弱引用”中属于最强的引用。SoftReference 所指向的对象,当没有强引用指向它时,会在内存中停留一段的时间, 垃圾回收器会根据 JVM内存的使用情况(内存的紧缺程度)以及 SoftReference 的 get() 方法的调用情况来决定是否对其进行回收。 具体使用一般是通过 SoftReference 的构造方法,将需要用弱引用来指向的对象包装起来。当需要使用的时候, 调用 SoftReference 的 get() 方法来获取。当对象未被回收时 SoftReference 的 get() 方法会返回该对象的强引用 软引用有以下特征: 1. 软引用使用 get() 方法取得对象的强引用从而访问目标对象。 2. 软引用所指向的对象按照 JVM 的使用情况(Heap 内存是否临近阈值)来决定是否回收。 3. 软引用可以避免 Heap 内存不足所导致的异常。 当垃圾回收器决定对其回收时,会先清空它的 SoftReference,也就是说 SoftReference 的 get() 方法将会返回 null, 然后再调用对象的 finalize() 方法,并在下一轮 GC 中对其真正进行回收。 WeakReference WeakReference 是弱于 SoftReference 的引用类型。弱引用的特性和基本与软引用相似,区别就在于弱引用所指向的对象只要进行系统垃圾回收, 不管内存使用情况如何,永远对其进行回收(get() 方法返回 null) 弱引用有以下特征: 1.弱引用使用 get() 方法取得对象的强引用从而访问目标对象。 2.一旦系统内存回收,无论内存是否紧张,弱引用指向的对象都会被回收。 3.弱引用也可以避免 Heap 内存不足所导致的异常。 PhantomReference PhantomReference 是所有“弱引用”中最弱的引用类型。不同于软引用和弱引用,虚引用无法通过 get() 方法来取得目标对象的强引用从而使用目标对象, 观察源码可以发现 get() 被重写为永远返回 null。那虚引用到底有什么作用?其实虚引用主要被用来 跟踪对象被垃圾回收的状态, 通过查看引用队列中是否包含对象所对应的虚引用来判断它是否 即将被垃圾回收,从而采取行动。它并不被期待用来取得目标对象的引用,而目标对象被回收前, 它的引用会被放入一个 ReferenceQueue 对象中,从而达到跟踪对象垃圾回收的作用。所以具体用法和之前两个有所不同,它必须传入一个 ReferenceQueue 对象。当虚引用所引用对象被垃圾回收后,虚引用会被添加到这个队列中。 值得注意的是,对于引用回收方面,虚引用类似强引用不会自动根据内存情况自动对目标对象回收,Client 需要自己对其进行处理以防 Heap 内存不足异常 虚引用有以下特征: 1.虚引用永远无法使用 get() 方法取得对象的强引用从而访问目标对象。 2.虚引用所指向的对象在被系统内存回收前,虚引用自身会被放入 ReferenceQueue 对象中从而跟踪对象垃圾回收。 3.虚引用不会根据内存情况自动回收目标对象 小结: 另外值得注意的是,其实 SoftReference, WeakReference 以及 PhantomReference 的构造函数都可以接收一个 ReferenceQueue 对象。 当 SoftReference 以及 WeakReference 被清空的同时,也就是 Java 垃圾回收器准备对它们所指向的对象进行回收时,调用对象的 finalize() 方法之前, 它们自身会被加入到这个 ReferenceQueue 对象中,此时可以通过 ReferenceQueue 的 poll() 方法取到它们。而 PhantomReference 只有当 Java 垃圾回收器对其所指向的对象真正进行回收时,会将其加入到这个 ReferenceQueue 对象中,这样就可以追综对象的销毁情 */ public static void main(String[] args) throws Exception { // 设置jvm参数 // -Xmx2m -Xms2m // test_weakReference(); // test_weakReference2(); // test_softReference(); // test_phantomReference(); // 测试oom时,把finalize方法的打印语句注释掉 // test_strongReference_OOM(); // test_weakReference_OOM(); // test_softReference_OOM(); test_phantomReference_OOM(); } // result: // weak ref // weak ref is finalizing at Sat Feb 08 23:54:17 CST 2014 // null (可能不为null,因为gc不一定执行) static void test_weakReference() throws Exception { // 声明一个弱引用 Reference<Bean> ref = new WeakReference<Bean>(new Bean("weak ref")); // WeakReference通过get方法返回指向目标对象的强引用 System.out.println(ref.get()); // 建议jvm进行gc System.gc(); System.runFinalization(); TimeUnit.SECONDS.sleep(3); // 一旦jvm执行gc,会调用Reference的clear方法,清空referent,此时get方法返回值为null System.out.println(ref.get()); } // result: // false // weak ref // null // weak ref is finalizing at Sun Feb 09 00:08:00 CST 2014 // true // null // java.lang.ref.WeakReference@16caf43 static void test_weakReference2() throws Exception { ReferenceQueue<Bean> queue = new ReferenceQueue<Bean>(); Reference<Bean> ref = new WeakReference<Bean>(new Bean("weak ref"), queue); // 如果该引用对象被加入到关联的queue中了,返回true System.out.println(ref.isEnqueued()); System.out.println(ref.get()); System.out.println(queue.poll()); System.gc(); System.runFinalization(); TimeUnit.SECONDS.sleep(3); System.out.println(ref.isEnqueued()); System.out.println(ref.get()); System.out.println(queue.poll()); } // result: // soft ref // soft ref is finalizing at Sun Feb 09 00:13:29 CST 2014 // null static void test_softReference() throws Exception { Reference<Bean> ref = new SoftReference<Bean>(new Bean("soft ref")); System.out.println(ref.get()); // 模拟消耗内存操作 SoftReference<String>[] garbage = new SoftReference[100000]; for (int i = 0; i < garbage.length; i++) { garbage[i] = new SoftReference<String>(new String("gb")); } TimeUnit.SECONDS.sleep(3); System.out.println(ref.get()); } // result: // null // false // null // phantom ref is finalizing at Sun Feb 09 00:16:26 CST 2014 // null // true // java.lang.ref.PhantomReference@60aeb0 static void test_phantomReference() throws Exception { ReferenceQueue<Bean> queue = new ReferenceQueue<Bean>(); Reference<Bean> ref = new PhantomReference<Bean>( new Bean("phantom ref"), queue); // PhantomReference的get方法永远返回null System.out.println(ref.get()); System.out.println(ref.isEnqueued()); System.out.println(queue.poll()); System.gc(); TimeUnit.SECONDS.sleep(3); System.gc(); System.out.println(ref.get()); System.out.println(ref.isEnqueued()); System.out.println(queue.poll()); } static final int SIZE = 100000; // OOM static void test_strongReference_OOM() { Bean[] beans = new Bean[SIZE]; for (int i = 0; i < beans.length; i++) beans[i] = new Bean("strong ref " + i); } // no OOM static void test_weakReference_OOM() { @SuppressWarnings("unchecked") Reference<Bean>[] refs = new WeakReference[SIZE]; for (int i = 0; i < refs.length; i++) refs[i] = new WeakReference<Bean>(new Bean("weak ref " + i)); System.out.println(refs[1000].get()); } // no OOM static void test_softReference_OOM() { @SuppressWarnings("unchecked") Reference<Bean>[] refs = new SoftReference[SIZE]; for (int i = 0; i < refs.length; i++) refs[i] = new SoftReference<Bean>(new Bean("soft ref " + i)); System.out.println(refs[1000].get()); } // OOM static void test_phantomReference_OOM() { ReferenceQueue<Bean> queue = new ReferenceQueue<Bean>(); @SuppressWarnings("unchecked") Reference<Bean>[] refs = new PhantomReference[SIZE]; for (int i = 0; i < refs.length; i++) refs[i] = new PhantomReference<Bean>(new Bean("soft ref " + i), queue); } } class Bean { String name; public Bean(String name) { this.name = name; } @Override public String toString() { return name; } @Override protected void finalize() throws Throwable { // System.out.println(name + " is finalizing at " + new Date()); } }
参考
http://www.ibm.com/developerworks/cn/java/j-lo-langref/index.html?ca=drs-
http://zhang-xzhi-xjtu.iteye.com/blog/413159
发表评论
-
redis安装(windows.exe)
2014-05-21 22:54 747https://github.com/rgl/redis ... -
rabbitMQ安装(windows下)
2014-05-21 22:41 686进入项目下载主页面http://www.rabbitmq.co ... -
实现单线程的断点下载
2014-04-16 09:43 850/** * 实现单线程的断点下载 */ publ ... -
实现一个简易的http模拟器
2014-04-15 15:20 1814/** * http模拟器 * 模拟发送http请求和 ... -
xml学习鉴定
2014-04-09 23:33 846实现招生录取系统中的 ... -
xml学习
2014-04-08 22:47 1480XML:Extensible Markup Langu ... -
HTTP断点续传
2014-03-31 22:13 803http://fenglingcorp.iteye.com/b ... -
java多线程-线程状态转换
2014-03-01 09:20 8051. 新建(new):新创建了一个线程对象。 2. 可 ... -
apt处理自定义annotation
2014-02-19 23:20 1030package annotations; import ... -
跳过UTF-8的BOM
2014-02-14 12:19 1510/** version: 1.1 / 2007-01-25 ... -
不带头结点的单链表面试汇总
2014-01-24 13:47 1501import java.io.ByteArrayInputSt ... -
带头节点的单链表面试题汇总
2014-01-23 15:12 1035import java.io.ByteArrayInput ... -
单链表面试题之-链表反转
2014-01-15 22:43 1108单链表反转 -------------------- ... -
java单链表-带头结点和不带头结点单链表的简单实现
2014-01-14 23:41 4936带头结点的单链表实现 public class LinkedL ... -
ClassLoader
2013-11-08 15:57 920public class ClassLoaderTest { ... -
URL和URI
2013-11-08 13:48 525private static void getData ... -
i++和++i
2013-11-06 15:26 531// i = i++ 计算过程 // temp = i; ... -
java 继承 多态
2013-11-06 15:19 815/** 运行结果: A's constructor co ... -
sealing violation
2013-11-03 16:10 3154一般以下两种情况会触发sealing安全异常 1)当被密封(s ... -
hashmap分析
2013-10-30 15:20 703/** hashmap底层维护着一个entry数组,每 ...
相关推荐
Your author likes to read reference manuals (believe it or not)—at least if they are reasonably complete—on the grounds that this is the most efficient way to absorb a language quickly.
Java in a Nutshell Java Language Reference Java AWT Reference Java Fundamental Classes Reference Exploring Java Combined Index Combined Search Web Version Credits
### Neo4j Java Reference 3.0:深入理解图数据库扩展与高级应用 #### 概述 《Neo4j Java Reference 3.0》是一本详细介绍如何使用Java语言来开发和扩展Neo4j图数据库的专业指南。本书不仅覆盖了Neo4j的核心功能,...
### 伯克利:A Java Reference —— Java概述与基础知识详解 #### 1. Java概述 本章节提供了Java编程语言的基础介绍,从程序结构、编译执行到简单值与表达式的处理进行了详尽的讲解。 ##### 1.1 基本程序结构 ...
Java reference sheet
Java Reference源码解析 Java Reference是Java语言的一种机制,用于追踪对象的可达性和垃圾回收。Java Reference源码解析主要为大家详细解析了Java Reference源码,具有一定的参考价值,感兴趣的小伙伴们可以参考...
Java: The Complete Reference, Eleventh Edition By 作者: Herbert Schildt ISBN-10 书号: 1260440230 ISBN-13 书号: 9781260440232 Edition 版本: 11 出版日期: 2018-12-12 pages 页数: (1955) The Definitive ...
在Java编程语言中,`Reference`类是一个非常特殊且重要的概念,它超出了常规的引用类型,如`Object`或数组引用。`Reference`类及其子类主要用于处理对象的软引用、弱引用和虚引用,这些引用类型在内存管理,特别是...
Java The Complete Reference, 11th Edition 9781260440232 c.pdf Java The Complete Reference, 11th Edition 9781260440232 c.pdf Java The Complete Reference, 11th Edition 9781260440232 c.pdf
在Neo4j-java-reference-3.3这份参考指南中,涵盖了多个关于如何在Java环境中使用和扩展Neo4j数据库的高级主题。文档内容涉及到如何嵌入Neo4j到Java应用中、使用Neo4j的遍历框架、手动索引、事务管理、在线备份以及...
Java The Complete Reference 10th Edition Java9 编程官方参考(第10版) 带书签 文字版
Neo4j的Java参考文档版本3.3详细介绍了如何在Java应用程序中嵌入Neo4j,扩展Neo4j的功能,并且介绍了如何使用REST API进行授权规则设置、远程调试配置、事务管理、手动索引、在线备份以及监控Neo4j的JMX指标。...
Java自发布以来,已经经历了多个版本的迭代,目前最新的稳定版为Java 14,但本文档提及的《Java The Complete Reference 9th》涉及的Java版本是第九版对应的Java技术标准。 提到的《Java The Complete Reference 9...
### Java AWT(Abstract Window Toolkit)详解:掌握Java图形用户界面设计的核心技能 #### 引言:Java AWT——构建用户界面的基石 在Java的世界里,Abstract Window Toolkit(AWT)扮演着至关重要的角色,它为Java...
在Java编程语言中,"reference"是一个至关重要的概念,它涉及到对象的引用和内存管理。在Java的世界里,"Everything is Object",这意味着所有的数据都以对象的形式存在,而reference则是连接这些对象与程序代码的...
这将是一个Java Swing应用程序,它将用作Java API名称的快速参考。 它将具有增量搜索和过滤功能,从而提高了搜索效率。 这将是非常简单并且是统计分析Java api的好方法。
《Java The Complete Reference 第九版源代码》是一个深入学习Java编程语言的重要资源。这个压缩包包含的源代码是作者在书中讲解各种Java概念和技术时所使用的示例程序,旨在帮助读者更好地理解和应用Java编程知识。...
这个压缩包中的源代码文件名为"javareference",很可能是该章节所有示例的集合。 在Java编程中,源代码是用Java语言编写的程序文本,包含了类定义、方法、变量和控制流程等元素。这些源代码经过Java编译器的处理,...
《neo4j-java-reference-3.1》是Neo4j官方发布的针对Java开发者的详细指南,旨在帮助开发者熟练地利用Java API与Neo4j图形数据库进行交互。这本书涵盖了从安装配置到高级特性的方方面面,是Java程序员在 Neo4j 领域...