如何打印出java weakreferencee的实体

Java中的 WeakReference 和 SoftReference_Java教程_动态网站制作指南
Java中的 WeakReference 和 SoftReference
来源:人气:467
中的 WeakReference 和 SoftReference我们知道Java语言中没有指针,取而代之的是引用reference。Java中的引用又可以分为四种:强引用,弱引用(WeakReference),软引用(SoftReference),虚引用(PhantomReference)。其中强引用,就是我们平时使用的最多的最普通的引用,虚引用一般我们是没有机会使用到的。所以我们主要了解下 WeakReference 和 SoftReference(除了上面说的四种引用之外,其实还有一种引用&&原子引用AtomicReference,用于并发编程环境)。1. 先上一段代码:public class ReferenceTest {
public static void main(String[] args){
LinkedList&byte[]& list = new LinkedList&&();
for(int i=0; i&1024; i++){
list.add(new byte[]);
}}上面的代码会抛出:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space堆内存溢出。因为我们不断的在堆上分配一个 1M 大小的 byte[]对象,并且将该引用加入到 list 中,循环1024次,需要占用 1G 的堆内存,从而导致 heap space OutOfMemory.2. 我们使用 WeekReference 对代码进行修改:public class ReferenceTest {
public static void main(String[] args) {
long beginTime = System.nanoTime();
LinkedList&WeakReference&byte[]&& list = new LinkedList&&();
for (int i = 0; i & 1024; i++) {
list.add(new WeakReference&&(new byte[1024 * 1024]));
long endTime = System.nanoTime();
System.out.intln(endTime - beginTime);
}}输出的结果: (0.19秒)我们发现堆内存溢出的错误没有了。这是什么原因呢。因为我们使用了 弱引用WeekReference 来引用堆上的 1M 的byte[]对象,而弱引用WeekReference引用的对象,如果仅仅只被弱引用,而没有被强引用的话,在下一次GC时,就会回收该对象占用的内存,所以不会内存溢出。3. 我们使用 SoftReference 对代码进行修改:public class ReferenceTest {
public static void main(String[] args) {
long beginTime = System.nanoTime();
LinkedList&SoftReference&byte[]&& list = new LinkedList&&();
for (int i = 0; i & 1024; i++) {
list.add(new SoftReference&&(new byte[1024 * 1024]));
long endTime = System.nanoTime();
System.out.println(endTime - beginTime);
}}输出结果: (1.5秒)我们发现堆内存溢出的错误也没有了。因为我们使用了 软引用SoftReference 来引用堆上的 1M 的byte[]对象,而软引用SoftReference引用的对象,如果仅仅只被软引用,而没有被强引用的话,在内存空间不足时,GC 就会回收该对象占用的内存,所以不会内存溢出。但是我们注意到 采用WeekReference和采用SoftReference所花费的时间,有接近10被的差距。原因应该是,SoftReference只有在内存空间不足时,GC才会回收对象占用的空间,而这时进行的是 full GC,full GC会导致 STW 程序暂停,所以花费的时间过多。4. 总结强引用:只要堆上的对象,被至少一个强引用所指向,那么GC就不会回收该对象的内存空间。弱引用:只要堆上的对象仅仅只被弱引用所指向,不管当前内存空间是否足够,下次GC都会回收对象的内存空间。软引用:只要堆上的对象仅仅只被软引用所指向,并且当内存空间不足时,GC才会回收对象的内存空间。WeakReference 和 SoftReference一般使用在构造一个缓存系统,比如使用一个map来构造。因为缓存系统是一个&全生命期&的对象,系统停止,缓存对象才会被销毁,所以当我们不断的想缓存对象中添加对象时,那么就会导致该缓存对象map所引用的对象越来越多,而因为是强引用,这些被放进map缓存了的对象不能被GC锁回收,那么就导致系统堆内存占用会越来越大,从而最终导致内存溢出。那么此时我们就可以使用 WeakReference 或 SoftReference了,将强引用通过WeakReference 和 SoftReference 包装之后,变成弱引用和软引用,那么当缓存中的对象,仅仅被缓存map锁引用时,那么分别在下次GC和内存不足GC时就会回收这些对象占用的内存。其实JDK给我们提供了一个专门的类:WeakHashMap ,弱引用的hashMap,所以构造缓存系统是,我们可以考虑使用它。其实这里引出了另外一个问题,jdk中众多的map,我们应该如何进行选择:HashMapConcurrentHashMapTreeMapWeakHashMapLinkedHashMapCollections.synchronizedMapHashtable等等。我们在选择一个map时,应该好好的考虑下,那个更加适合我们的需求。
优质网站模板推荐这篇日记的豆列
&&&&&&&&&&&&WeakReference::Resolve 方法
WeakReference::Resolve 方法
WeakReference::Resolve 方法
Visual Studio 2015
若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅 。支持 WRL基础结构,不应在代码中直接使用。
STDMETHOD(Resolve)
(REFIID riid,
_Deref_out_opt_ IInspectable **ppvObject
是一个ID接口。ppvObject
该操作完成,强烈当前的引用复制,则强引用计数是非零值。S_OK,如果该操作成功和强引用计数为零。
ppvObject 参数设置为 nullptr。S_OK,如果该操作成功和强引用计数为非零。
ppvObject 参数设置为强引用。否则,此 HRESULT 指示原因的此操作失败。则强引用计数是非零,将指定的强引用指向当前的值。头文件:implements.hMicrosoft::WRL::Details命名空间:
此页面有帮助吗?
更多反馈?
1500 个剩余字符
我们非常感谢您的反馈。前言: 看到篇帖子, 国外一个技术面试官在面试senior java developer的时候, 问到一个weak reference相关的问题. 他没有期望有人能够完整解释清楚weak reference是什么, 怎么用, 只是期望有人能够提到这个concept和java的GC相关. 很可惜的是, 20多个拥有5年以上java开发经验的面试者中, 只有两人知道weak reference的存在, 而其中只有一人实际用到过他. 无疑, 在interviewer眼中, 对于weak reference的理解和应用在面试中给了这一个interviewee相当多的加分. 所以, 将我对于这个技术的理解和使用总结在这篇博客里, 希望读者和自己通过读和写这篇帖子, 能够在以后的工作和面试中获得加分.
在Java里, 当一个对象o被创建时, 它被放在Heap里. 当GC运行的时候, 如果发现没有任何引用指向o, o就会被回收以腾出内存空间. 或者换句话说, 一个对象被回收, 必须满足两个条件: 1)没有任何引用指向它 2)GC被运行.
在现实情况写代码的时候, 我们往往通过把所有指向某个对象的referece置空来保证这个对象在下次GC运行的时候被回收 (可以用java -verbose:gc来观察gc的行为)
Object c = new Car();
但是, 手动置空对象对于程序员来说, 是一件繁琐且违背自动回收的理念的.
对于简单的情况, 手动置空是不需要程序员来做的, 因为在java中, 对于简单对象, 当调用它的方法执行完毕后, 指向它的引用会被从stack中popup, 所以他就能在下一次GC执行时被回收了.
但是, 也有特殊例外. 当使用cache的时候, 由于cache的对象正是程序运行需要的, 那么只要程序正在运行, cache中的引用就不会被GC给(或者说, cache中的reference拥有了和主程序一样的life cycle). 那么随着cache中的reference越来越多, GC无法回收的object也越来越多, 无法被自动回收. 当这些object需要被回收时, 回收这些object的任务只有交给程序编写者了. 然而这却违背了GC的本质(自动回收可以回收的objects).
所以, java中引入了weak reference. 相对于前面举例中的strong reference:
Object c = new Car(); //只要c还指向car object, car object就不会被回收
当一个对象仅仅被weak reference指向, 而没有任何其他strong reference指向的时候, 如果GC运行, 那么这个对象就会被回收. weak reference的语法是:
WeakReference&Car& weakCar = new WeakReference(Car)(car);
当要获得weak reference引用的object时, 首先需要判断它是否已经被回收:
weakCar.get();
如果此方法为空, 那么说明weakCar指向的对象已经被回收了.
下面来看一个例子:
* @author wison
public class Car {
public Car(double price, String colour){
this.price =
this.colour =
public double getPrice() {
public void setPrice(double price) {
this.price =
public String getColour() {
public void setColour(String colour) {
this.colour =
public String toString(){
return colour +&car costs $&+
import java.lang.ref.WeakR
* @author wison
public class TestWeakReference {
public static void main(String[] args) {
Car car = new Car(22000,&silver&);
WeakReference&Car& weakCar = new WeakReference&Car&(car);
while(true){
if(weakCar.get()!=null){
System.out.println(&Object is alive for &+i+& loops - &+weakCar);
System.out.println(&Object has been collected.&);
在上例中, 程序运行一段时间后, 程序打印出&Object has been collected.& 说明, weak reference指向的对象的被回收了.
值得注意的一点, 即使有
car引用指向对象, 且
car是一个strong reference, weak reference weakCar指向的对象仍然被回收了. 这是因为java的编译器在发现进入while循环之后,
car已经没有被使用了, 所以进行了优化(将其置空?). 当把TestWeakReference.java修改为:
import java.lang.ref.WeakR
* @author wison
public class TestWeakReference {
public static void main(String[] args) {
Car car = new Car(22000,&silver&);
WeakReference&Car& weakCar = new WeakReference&Car&(car);
while(true){
System.out.println(&here is the strong reference &car& &+car);
if(weakCar.get()!=null){
System.out.println(&Object is alive for &+i+& loops - &+weakCar);
System.out.println(&Object has been collected.&);
weak reference指向的object就不会被回收了. 因为还有一个strong reference
car指向它.
* WeakReference的一个特点是它何时被回收是不可确定的, 因为这是由GC运行的不确定性所确定的. 所以, 一般用weak reference引用的对象是有价值被cache, 而且很容易被重新被构建, 且很消耗内存的对象.
ReferenceQueue
在weak reference指向的对象被回收后, weak reference本身其实也就没有用了. java提供了一个ReferenceQueue来保存这些所指向的对象已经被回收的reference. 用法是在定义WeakReference的时候将一个ReferenceQueue的对象作为参数传入构造函数.
其他类型的references
-SoftReference
soft reference和weak reference一样, 但被GC回收的时候需要多一个条件: 当系统内存不足时(GC是如何判定系统内存不足? 是否有参数可以配置这个threshold?), soft reference指向的object才会被回收. 正因为有这个特性, soft reference比weak reference更加适合做cache objects的reference. 因为它可以尽可能的retain cached objects, 减少重建他们所需的时间和消耗.
-phantomReference
这个还没想到应用场景, 就先不说了. 有人在实践中用到了的话, 欢迎分享.
WeakHashMap
to be continued
相关 [面试 java weakreference] 推荐:
- Java - 编程语言 - ITeye博客
前言: 看到篇帖子, 国外一个技术面试官在面试senior java developer的时候, 问到一个weak reference相关的问题. 他没有期望有人能够完整解释清楚weak reference是什么, 怎么用, 只是期望有人能够提到这个concept和java的GC相关. 很可惜的是, 20多个拥有5年以上java开发经验的面试者中, 只有两人知道weak reference的存在, 而其中只有一人实际用到过他.
- Java - 编程语言 - ITeye博客
 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面. 抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节. 抽象包括两个方面,一是过程抽象,二是数据抽象.  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法. 对象的一个新类可以从现有的类中派生,这个过程称为类继承.
- CSDN博客编程语言推荐文章
  这个系列面试题主要目的是帮助你拿轻松到offer,同时还能开个好价钱. 只要能够搞明白这个系列的绝大多数题目,在面试过程中,你就能轻轻松松的把面试官给忽悠了. 对于那些正打算找工作JAVA软件开发工作的童鞋们来说,当你看到这份题目的时候,你应该感动很幸运,因为,只要你把题目中的内容都搞懂了,在笔试的时候就可以游刃有余,通过面试只有半步之遥了,笔试只能反映你的JAVA技能.
- Java - 编程语言 - ITeye博客
Java基础部分......................................................................................................2. 1、一个".java"源文件中是否可以包括多个类(不是内部类). 2、Java有没有goto?..........................................................................................2.
- 企业架构 - ITeye博客
学习笔记,转自:
/topic/1033375. 学习笔记,转自:
http://download.csdn.net/detail/ht9. 一是CPU操作的快慢,二是IO操作的快慢. 赋值和计算,如:m = i*j;. 流程控制,如:while(true) { i ++;}.
- 编程语言 - ITeye博客
1.String、StringBuffer、StringBuilder的区别. 2.冒泡算法的时间复杂度. 3.部门表 dept
包含deptno编号,deptname 名称
,adress地址. 员工表emp
包含empno编号,empname名称,sal工资,deptno部门编号. (1).一条sql语句查询出所有高于部门平均公司的员工信息(包含部门名称).
- ImportNew
查看不同公司新鲜真实的Java面试题,摘自. 假设有一个 getNextparson() 方法返回 Person 对象,Person 类实现了 comparable 接口,现在从文件中读取记录并排序,然后给出前 1000 条记录,纸上作答. 写一个函数,传入 2 个有序的整数数组,返回一个有序的整数数组.
- sun - IT程序员面试网
线程:是指进程中的一个执行流程. 线程与进程的区别:每个进程都需要操作系统为其分配独立的内存地址空间,而同一进程中的所有线程在同一块地址空间中工作,这些线程可以共享同一块内存和系统资源. 创建线程有两种方式,如下:
1、 扩展java.lang.Thread类
2、 实现Runnable接口
Thread类代表线程类,它的两个最主要的方法是:
run()——包含线程运行时所执行的代码
Start()——用于启动线程.
- ImportNew
本文我们将要讨论Java面试中的各种不同类型的面试题,它们可以让雇主测试应聘者的Java和通用的面向对象编程的能力. 下面的章节分为上下两篇,
第一篇将要讨论面向对象编程和它的特点,关于Java和它的功能的常见问题,Java的集合类,垃圾收集器,
第二篇主要讨论异常处理,Java小应用程序,Swing,JDBC,远程方法调用(RMI),Servlet和JSP.
- ImportNew
第一篇讨论了面向对象编程和它的特点,关于Java和它的功能的常见问题,Java的集合类,垃圾收集器,本章主要讨论异常处理,Java小应用程序,Swing,JDBC,远程方法调用(RMI),Servlet和JSP. Java小应用程序(Applet). 43.Java中的两种异常类型是什么. Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常.
--> 坚持分享优质有趣的原创文章,并保留作者信息和版权声明,任何问题请联系:@。}

我要回帖

更多关于 weakreference 监听 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信