Reference

Reference

概述

Abstract base class for reference objects.
This class defines the operations common to all reference objects.
Because reference objects are implemented in close cooperation with the garbage collector, this class may not be subclassed directly.

引用对象的基类;

定义了所有引用对象的基本行为;

  

 

SoftReference

概述

内存不足时被GC回收

Soft reference objects, which are cleared at the discretion of the garbage collector in response to memory demand.
Soft references are most often used to implement memory-sensitive caches.

软引用对象,GC根据内存需求自行决定clear;

 

Suppose that the garbage collector determines at a certain point in time that an object is <a href="package-summary.html#reachability">softly reachable.
At that time it may choose to clear atomically all soft references to that object and all soft references to any other softly-reachable objects from which that object is reachable through a chain of strong references.
At the same time or at some later time it will enqueue those newly-cleared soft references that are registered with reference queues.

 

All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an <code>OutOfMemoryError</code>.
Otherwise no constraints are placed upon the time at which a soft reference will be cleared or the order in which a set of such references to different objects will be cleared.
Virtual machine implementations are, however, encouraged to bias against clearing recently-created or recently-used soft references.

在JVM抛出OutOfMemoryError之前,软引用对象保证被clear;

 

Direct instances of this class may be used to implement simple caches; this class or derived subclasses may also be used in larger data structures to implement more sophisticated caches.
As long as the referent of a soft reference is strongly reachable, that is, is actually in use, the soft reference will not be cleared.
Thus a sophisticated cache can, for example, prevent its most recently used entries from being discarded by keeping strong referents to those entries, leaving the remaining entries to be discarded at the discretion of the garbage collector.

实例可以用来实现Caches;

 

public class SoftReference<T> extends Reference<T> {

        /**
         * Timestamp clock, updated by the garbage collector
         */
        static private long clock;

        /**
         * Timestamp updated by each invocation of the get method.
         * The VM may use this field when selecting soft references to be cleared, but it is not required to do so.
         */
        private long timestamp;

        /**
         * Creates a new soft reference that refers to the given object.
         * The new reference is not registered with any queue.
         */
        public SoftReference(T referent) {
            super(referent);
            this.timestamp = clock;
        }

        /**
         * Returns this reference object's referent.
         * If this reference object has been cleared, either by the program or by the garbage collector, then this method returns <code>null</code>.
         */
        public T get() {
            T o = super.get();
            if (o != null && this.timestamp != clock)
                this.timestamp = clock;
            return o;
        }
    }

 

示例  

static void softTest(){
        // -Xms10m -Xmx10m -verbose:gc
        SoftReference<User> softReference = new SoftReference<User>(new User(1));

        System.out.println(softReference.get());

        System.gc();
        System.out.println("after gc...");

        System.out.println(softReference.get()); // 由于内存空间足,不会回收软引用对象

        try {
            byte[] bytes = new byte[1024*1024*7];
        }catch (Throwable e){
            e.printStackTrace();
        }finally {
            System.out.println(softReference.get()); // 由于内存空间不足,回收软引用对象
        }
    }

    @AllArgsConstructor
    @Data
    private static class User {
        private int age;

        @Override
        protected void finalize() throws Throwable {
            System.out.println("gc call finalize...");
        }
    }


结果:
SoftRefTest.User(age=1)
[GC (System.gc())  1580K->544K(9728K), 0.0008685 secs]
[Full GC (System.gc())  544K->394K(9728K), 0.0040107 secs]
after gc...
SoftRefTest.User(age=1)
[GC (Allocation Failure)  454K->490K(9728K), 0.0006661 secs]
[GC (Allocation Failure)  490K->458K(9728K), 0.0005046 secs]
[Full GC (Allocation Failure)  458K->394K(9728K), 0.0036571 secs]
[GC (Allocation Failure)  394K->394K(9728K), 0.0003530 secs]
[Full GC (Allocation Failure)  394K->377K(9728K), 0.0037976 secs]
gc call finalize...
null
java.lang.OutOfMemoryError: Java heap space
	at reftest.SoftRefTest.softTest(SoftRefTest.java:35)
	at reftest.SoftRefTest.main(SoftRefTest.java:19)

  

WeakReference

概述

只要GC就被回收

Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed.
Weak references are most often used to implement canonicalizing mappings.

WeakReference实例 不会阻止 其所指的对象 被finalize;

WeakReference实例  通常被用来实现mappings;


Suppose that the garbage collector determines at a certain point in time that an object is <a href="package-summary.html#reachability">weakly reachable</a>.
At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references.
At the same time it will declare all of the formerly weakly-reachable objects to be finalizable.
At the same time or at some later time it will enqueue those newly-cleared weak references that are registered with reference queues.

假设GC在某个时间点 发现对象是weakly reachable

 

 

public class WeakReference<T> extends Reference<T> {
        /**
         * Creates a new weak reference that refers to the given object.
         * The new reference is not registered with any queue.
         */
        public WeakReference(T referent) {
            super(referent);
        }

        /**
         * Creates a new weak reference that refers to the given object and is
         * registered with the given queue.
         */
        public WeakReference(T referent, ReferenceQueue<? super T> q) {
            super(referent, q);
        }
    }

  

示例

public static void main(String[] args) throws InterruptedException {
        WeakReference<MyObject> weakReference = new WeakReference<>(new MyObject("jack"));

        System.out.println(weakReference.get());

        // 强制触发一次垃圾回收
        System.gc();

        Thread.sleep(100);

        System.out.println(weakReference.get());
    }

    @AllArgsConstructor
    @Data
    static class MyObject {
        private String id;

        @Override
        protected void finalize() throws Throwable {
            System.out.println("gc call finalize...");
        }
    }


结果:
WeakRefTest.MyObject(id=jack)
[GC (System.gc())  3938K->536K(251392K), 0.0011775 secs]
[Full GC (System.gc())  536K->397K(251392K), 0.0057707 secs]
gc call finalize...
null

  

   

PhantomReference

概述

Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed.
Phantom references are most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.

虚引用对象,当GC确定其引用对象可以被回收后排队;

虚引用对象 通常用于比Java finalize机制更灵活的 事前清理操作;

 

If the garbage collector determines at a certain point in time that the referent of a phantom reference is phantom reachable, then at that time or at some later time it will enqueue the reference.

如果GC 在某个时间点 确定某个虚引用对象 是虚可达,在那时或稍后,将该引用排队;

 

In order to ensure that a reclaimable object remains so, the referent of a phantom reference may not be retrieved: The <code>get</code> method of a phantom reference always returns <code>null</code>.

在排队后,为了确保可回收对象保持,在get时,始终返回null;

 

Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued.
An object that is reachable via phantom references will remain so until all such references are cleared or themselves become unreachable.

 

 

public class PhantomReference<T> extends Reference<T> {

        /**
         * Returns this reference object's referent.
         * Because the referent of a phantom reference is always inaccessible, this method always returns null; 
         * @return
         */
        public T get() {
            return null;
        }

        public PhantomReference(T referent, ReferenceQueue<? super T> q) {
            super(referent, q);
        }
    }

  

posted on 2023-11-24 19:55  anpeiyong  阅读(54)  评论(0编辑  收藏  举报

导航