Reference counting GC has the problem of circular references, which makes it impossible to identify useless objects, while GC ROOT does not have the problem of circular references

The implementation mechanism of reference counting and GC ROOT is easy to understand, and everyone should be able to respond fluently in an interview, so how do you stand out? Consider a question: how do you solve the problem of circular references by using reference counting instead of GC ROOT?

Before answering this question, use a goal-driven approach to imagine how you can apply this knowledge to an interview:

Interviewer: Tell me about the garbage collection system

I:… You can solve the reference counting problem by using a combination of strong and weak reference counting, which is actually how Android’s smart Pointers are implemented…

Smart Pointers

Smart pointer is widely used in Android project, binder source code can be seen in SP, WP type reference:

 sp<IBinder> result = new BpBinder(handle);

 wp<IBinder> result = new BpBinder(handle);
Copy the code

Sp; strong pointer Wp is an weak pointer reference.

In Java, we don’t need to worry about object destruction and memory release, GC mechanism will automatically identify garbage objects, and smart pointer is a small GC implementation of native layer.

Smart Pointers identify useless objects by reference counting. Objects using smart Pointers must inherit from RefBase, which maintains the number of strong references and weak references of this object.

The strong pointer sp overrides the “=” operator to make the strong reference count +1 when referring to other objects, and the strong reference count -1 in the SP destructor. When the strong reference count drops to 0, the referenced object is destroyed.

When a weak pointer refers to another object, the weak reference count is +1. In WP destructor, the weak reference count is -1. When the strong reference count is 0, the referenced object is destroyed whether the weak reference count is 0 or not.

How to solve the circular reference problem

Weak references are used to solve the problem of circular references, which can never be freed:

If A strongly references B, A weak reference is required when B references A. When determining whether the object is useless, only the strong reference count is 0, and the number of weak reference counts is not concerned

This solves the problem of looping references that make the object unfreefall, but it causes the wild pointer problem: by the time B tries to access A through A weak pointer, A may have already been destroyed, and the weak pointer to A becomes A wild pointer. In this case, A does not exist and needs to be recreated

Smart pointer custom rules

Smart Pointers are not fixed “when the strong reference count is zero, destroy the referenced object regardless of whether the weak reference count is zero”, but can be customized rules. RefBase provides the extendObjectLifetime() method, which can be used to set rules that reference counters. Different rules can determine when to delete a target object, including the following three rules:

OBJECT_LIFETIME_STRONG: The object is destroyed only if the strong counter in the object’s memory space is 0

OBJECT_LIFETIME_WEAK: The object is destroyed only if both strong and weak counters in the object’s memory space are 0

OBJECT_LIFETIME_MASK: no matter if both of these counters are 0 or not, the object is not destroyed, just like normal Pointers, or the object must be released manually