Reprinted from www.cnblogs.com/lwbqqyumidi…

There are four types of reference in Java:

  • Strong reference
  • Soft Reference Soft Reference
  • Weak Reference
  • Phantom Reference

1. Strong reference

In practical programming, the most common reference type is of the form A A = new A(). The strong reference itself is stored in stack memory, pointing to the object in heap memory. If an object in heap memory no longer has any references to it, such as a= NULL, then it will be collected when garbage collection occurs.

2. Soft references

The common forms of soft references are as follows:

A a = new A();
SoftReference<A> srA = new SoftReference<A>(a);
Copy the code

Create a SoftReference object with a strong reference to the object and point to it with a weak reference to srA. If a= NULL, what happens when garbage collection?

import java.lang.ref.SoftReference;

public class ReferenceTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a = new A();
		SoftReference<A> softA = new SoftReference<A>(a);
		
		a = null;
		
		if(softA.get() == null){
			System.out.println("Has been recycled....");
		}else {
			System.out.println("Not recycled....");
		}
		
		// Garbage collection
		System.gc();
		
		if(softA.get() == null){
			System.out.println("Has been recycled....");
		}else {
			System.out.println("Not recycled...."); }}}class A{}Copy the code

The output

Not collected.... Not collected....Copy the code

When a=null, an object in heap memory will no longer have any strong references to it, but soft references to it. The first call to soft.get() starts without GC and returns a value. After A later forced GC, the A object is still not collected. So when do objects indicated by soft references start to be garbage collected? The following two conditions must be met:

  1. When the object it indicates does not have any strong reference objects pointing to it;

2. If the VM memory is insufficient

3. A weak reference

like

A a = new A();
WeakReference<A> wrA = new WeakReference<A>(a);
Copy the code

Test the above code again

import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class ReferenceTest { public static void main(String[] args) { // TODO Auto-generated method stub A a = new A(); WeakReference<A> softA = new WeakReference<A>(a); a = null; If (softA. The get () = = null) {System. Out. Println (" has been recycling..." ); }else {system.out.println (" not called....") ); } // Garbage collection system.gc (); If (softA. The get () = = null) {System. Out. Println (" has been recycling..." ); }else {system.out.println (" not called....") ); } } } class A{ }Copy the code

The output

Not collected.... Has been recycled....Copy the code

WeakReference does not change the garbage collection time of the original strong reference object. Once it indicates that the object does not have any strong reference object, the object enters the normal garbage collection process. Its main usage scenarios are as follows: at present, there is a strong reference pointing to a strong reference object, at this time, due to business needs, it is necessary to increase the reference to this object, and at the same time, it does not want to change the garbage collection time of this reference. At this time, WeakReference just meets the demand, which is common in some life-cycle scenarios.

For SoftReference and WeakReference, there is also a constructor parameter named ReferenceQueue. When the object indicated by SoftReference or WeakReference is indeed garbage collected, The reference will be placed in the ReferenceQueue. Note that in the above, when the get() method of SoftReference or WeakReference returns NULL, it only indicates that the object indicated has entered the garbage collection process, and the object may not be garbage collected. A reference will only be placed in the ReferenceQueue if it is confirmed to be garbage collected.

public class ReferenceTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		A a = new A();
	
		ReferenceQueue<A> rq = new ReferenceQueue<>();
		WeakReference<A> softA = new WeakReference<A>(a,rq);
		
		a = null;
		
		if(softA.get() == null){
			System.out.println("Object A enters garbage collection process....");
		}else {
			System.out.println("Not recycled....");
		}
		
		System.out.println("rq item:" + rq.poll());
		
		// Garbage collection
		System.gc();
		
		if(softA.get() == null){
			System.out.println("Object A enters garbage collection process....");
		}else {
			System.out.println("Not recycled....");
		}
		
		System.out.println("rq item:"+ rq.poll()); }}class A{
	@Override
	protected void finalize(a) throws Throwable {
		// TODO Auto-generated method stub
		super.finalize();
		System.out.println("In A Finalize, to be recycled immediately"); }}Copy the code

Running results:

Not collected.... rq item:nullObject a enters the garbage collection process.... rq item:nullIn A finalize, to be recycled immediatelyCopy the code

4. Virtual reference

Compared with SoftReference or WeakReference, PhantomReference has the following main differences: Refertomreference (T referent, ReferenceQueue<? Super T> q), therefore, PhantomReference must be used in conjunction with ReferenceQueue; 2.. PhantomReference’s get() method returns null regardless of whether there is a strong reference to the pointer object to PhantomReference.

public class ReferenceTest {

    public static void main(String[] args) {

        A a = new A();

        ReferenceQueue<A> rq = new ReferenceQueue<A>();
        PhantomReference<A> prA = new PhantomReference<A>(a, rq);

        System.out.println("prA.get():" + prA.get());

        a = null;

        System.gc();

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("rq item:"+ rq.poll()); }}class A {}Copy the code

The output is:

1 prA.get():null
2 rq item:java.lang.ref.PhantomReference@1da12fc0
Copy the code

Like WeakReference, PhantomReference does not change the garbage collection timing of its indicated object


Here are the Android references

Example of an error when using this Handler:

Android Studio will highlight this section in yellow as a warning

Issue: Ensures that Handler classes do not hold on to a reference to an outer class Id: HandlerLeak Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object.Copy the code

Since handler is defined as an inner class, GC may be prevented. If handler’s Looper or MessageQueue is not the main thread, then there is no problem. If handler’s Looper or MessageQueue is on the main thread, define handler as a static inner class. When you instantiate handler, pass in a weak reference to the outer class so that all members of the outer class can be used by weak references

There are a few points to note here: 1. The Looper life cycle of the main thread is the same as the Activity life cycle 2. Non-static inner classes, or anonymous inner classes. External class references are held by default.

Handler This anonymous inner class holds a reference to an external Activity, causing the Activity to fail to free its memory when it is destroyed

Correct use:

  • Defined as a static inner class
  • When can the Activity onDestroy () call handler. RemoveCallbacksAndMessages (null), then remove all the message in the queue

1. Why do anonymous inner classes hold references to external objects, and why can static inner classes solve this problem? 2. Why does this problem not occur on non-main threads? To solve these problems when I saw a series of articles, much better than I write, direct reprint zhuanlan.zhihu.com/p/78878986