Java Reference Types

References

Java provides two different types/classes of Reference Objects: strong and weak. Weak Reference Objects can be further divided into soft and phantom.

Strong Reference

StringBuilder builder = new StringBuilder(); 

This is the default type/class of Reference Object, if not differently specified: builder is a strong Reference Object. This kind of reference makes the referenced object not eligible for GC. That is, whenever an object is referenced by a chain of strong Reference Objects, it cannot be garbage collected.

Weak Reference

WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);

Weak Reference Objects are not the default type/class of Reference Object and to be used they should be explicitly specified like in the above example. This kind of reference makes the reference object eligible for GC. That is, in case the only reference reachable for the StringBuilder object in memory is, actually, the weak reference, then the GC is allowed to garbage collect the StringBuilder object. When an object in memory is reachable only by Weak Reference Objects, it becomes automatically eligible for GC.

Soft Reference

Garbage collector can collect an object if only weak references are pointing towards it and they are eagerly collected, on the other hand Objects with SoftReference are collected when JVM absolutely needs memory.

Phantom Reference

Object which only has Phantom reference pointing them can be collected whenever Garbage Collector likes it.

Useful Classes

WeakHashMap

Hash table based implementation of the Map interface, with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector, that is, made finalizable, finalized, and then reclaimed. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently from other Map implementations.

ReferenceQueue

If the garbage collector discovers an object that is weakly reachable, the following occurs:

  • The WeakReference object‘s referent field is set to null, thereby making it not refer to the heap object any longer.
  • The heap object that had been referenced by the WeakReference is declared finalizable.
  • The WeakReference object is added to its ReferenceQueue. Then the heap object‘s finalize() method is run and its memory freed.

When creating non-strong reference objects we have the option of passing a reference queue as a part of the Reference constructor. As seen from the above explanation, this reference queue is a way for the GC to inform the program that a certain object is no longer reachable.

Example

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class Test {
     public static void main(String[] args) throws InterruptedException {
         SavePoint savePoint = new SavePoint("Random"); // a strong object

         ReferenceQueue<SavePoint> savepointQ = new ReferenceQueue<SavePoint>();// the ReferenceQueue
         WeakReference<SavePoint> savePointWRefernce = new WeakReference<SavePoint>(savePoint, savepointQ);

         System.out.println("SavePoint created as a weak ref " + savePointWRefernce);
         Runtime.getRuntime().gc();
         System.out.println("Any weak references in Q ? " + (savepointQ.poll() != null));
         savePoint = null; // the only strong reference has been removed. The heap
         // object is now only weakly reachable

         System.out.println("Now to call gc...");
         Runtime.getRuntime().gc(); // the object will be cleared here - finalize will be called.

         System.out.println("Any weak references in Q ? " + (savepointQ.remove() != null));
         System.out.println("Does the weak reference still hold the heap object ? " + (savePointWRefernce.get() != null));
         System.out.println("Is the weak reference added to the ReferenceQ  ? " + (savePointWRefernce.isEnqueued()));

     }
}

class SavePoint {
    public SavePoint(String value) {

    }
}

The program :

  1. Creates a strong reference and adds it to a Weak reference savePointWRefernce. The object in memory is now referenced by a strong reference and a weak reference - hence strongly reachable.
  2. The first call to garbage collector will not clear our savepoint object as it is a strong reference. Hence the poll method of the referenceQ will return null. (poll method is non - blocking it checks and returns immediately.)
  3. The savePoint reference variable is set to null. Our heap object is now referenced only by the weak reference - hence it is weakly reachable.
  4. The second gc call will now locate the object, executes its finalize method and mark this object to be freed. Theobject is also added to the ReferenceQ.
  5. A call to the remove method of the ReferenceQ will return the object. remove is a blocking method. it will wait till an object has been made available in the Queue. (poll method might not work as the recycling process is happening on a separate thread.)

As seen once the object was ready to be released it was added to the reference queue. So the reference queue is like a callback to our java program, telling us that a particular object is released from its reference and is not available to our code anymore.

As seen from above the Reference queue actually holds within it the WeakReference which lost its heap object to clean up. The WeakReference does not have any association to the memory object. The get call above returns null. Unlike with finalize when we can make the object alive again, with the ReferenceQ there is no way to reach the released java object. Reference Queues are just for References that got freed by garbage collection. They cannot be used to make alive our objects again. They can only be used to notify our code about the loss of memory objects referred to by these non- strong references.

时间: 2024-08-01 03:44:08

Java Reference Types的相关文章

Java Reference &amp; ReferenceQueue一览

Overview The java.lang.ref package provides more flexible types of references than are otherwise available, permitting limited interaction between the application and the Java Virtual Machine (JVM) garbage collector. It is an important package, centr

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Types)

值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择. 它们有什么区别? 最基本的区别是 "值类型"

初探 C# 8 的 Nullable Reference Types

溫馨提醒:本文提及的 C# 8 新功能雖已通過提案,但不代表將來 C# 8 正式發布時一定會納入.這表示我這篇筆記有可能白寫了,也表示您不必急著瞭解這項新功能的所有細節,可能只要瞄一下底下的「概要」說明就夠了. 概要 C# 8 的 Nullable Reference Types 意味著往後所有的參考型別預設都是不可為 null:對於可為 null 的參考型別變數,寫法跟可為 null 的實質型別一樣,宣告時必須在型別後面加上 "?" 字元.請看以下範例: 1 int? num = n

What Influences Method Call Performance in Java?--reference

reference from:https://www.voxxed.com/blog/2015/02/too-fast-too-megamorphic-what-influences-method-call-performance-in-java/ Whats this all about then? Let’s start with a short story. I proposed a change on the a Java core libs mailing list to overri

理解java reference

Java世界泰山北斗级大作<Thinking In Java>切入Java就提出“Everything is Object”.在Java这个充满Object的世界中,reference是一切谜题的根源,所有的故事都是从这里开始的. Reference是什么? 如果你和我一样在进入Java世界之前曾经浪迹于C/C++世界,就一定不会对指针陌生.谈到指针,往日种种不堪回首的经历一下子涌上心头,这里不是抱怨的地方,让我们暂时忘记指针的痛苦,回忆一下最初接触指针的甜蜜吧!还记得你看过的教科书中,如何讲

Java Reference 源码分析

Reference对象封装了其它对象的引用,可以和普通的对象一样操作,在一定的限制条件下,支持和垃圾收集器的交互.即可以使用Reference对象来引用其它对象,但是最后还是会被垃圾收集器回收.程序有时候也需要在对象回收后被通知,以告知对象的可达性发生变更.  Java提供了四种不同类型的引用,引用级别从高到低分别为FinalReference,SoftReference,WeakReference,PhantomReference.其中FinalReference不对外提供使用.每种类型对应着

java reference(转)

http://blog.163.com/[email protected]/blog/static/112987702200962211145825/ 在Java中的引用类型,是指除了基本的变量类型之外的所有类型,所有的类型在内存中都会分配一定的存储空间(形参在使用的时候也会分配存储空间,方法调用完成之后,这块存储空间自动消失), 基本的变量类型只有一块存储空间(分配在stack中), 而引用类型有两块存储空间(一块在stack中,一块在heap中), 方法形参的值传递(引用)是指形参和传进来的

java.sql.Types,数据库字段类型,java数据类型的对应关系

从 JDBC 类型映射到 Java 类型 JDBC 类型 Java 类型 CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIMAL java.math.BigDecimal BIT boolean TINYINT byte SMALLINT short INTEGER int BIGINT long REAL float FLOAT double DOUBLE double BINARY

[sql]java.sql.Types的具体对应值(jdbcType)

public final static int BIT   =  -7; public final static int TINYINT  =  -6; public final static int SMALLINT =   5; public final static int INTEGER  =   4; public final static int BIGINT   =  -5; public final static int FLOAT   =   6; public final s