36

I am confused with the notion of "strong pointer" and "weak pointer". Diane Hackborn herself said that:

The object will remain around while there are strong pointers; it is destroyed once the last one is released. All you can do with a weak pointer is comparison and attempting to promote to a strong pointer; the latter will fail if there are no other strong pointers on the object.

Which is quite unclear to me. Is a strong pointer an equivalent of a (boost::)shared pointer? And what is the role of a weak pointer if it is there just to attempt to promote itself to a strong pointer? Like, when do we need weak and strong pointers?

Update:

Thank you everyone, but I'm asking specifically about android's kernel sp and wp, and they have nothing to do with Java's references at all.

Basically I'm trying to crack the code here http://www.androidenea.com/2010/03/share-memory-using-ashmem-and-binder-in.html And don't really understand the use of sp and wp

Update:

The actual answer lies in the comments of the accepted answer. Thanks to Gabe Sechan:

Strong and weak pointers are different smart pointer implementations and do about the same thing- when a pointer goes out of scope, so long as at least one strong pointer references it it will not be freed. If only weak pointers (or nothing) references it will be. The check is done whenever a strong or weak reference to it is descoped.

if I have 10 weak pointers referencing the same object, and one of those 10 goes out of scope, the object will be destroyed? Whereas with strong pointers, only when all 10 of them go out of scope will the object be destroyed?

Yes, almost. If all you have is 10 weak pointers, it would probably have gone out of scope already, when the last strong pointer went out of scope. The implementation may allow it to stick around a little while longer if there's spare memory, but it will be chopped if you go into a low memory condition and it doesn't sound like their implementation is that advanced from her quote. And the use of this is still mainly caching- it is roughly equivalent to a boost shared_ptr and boost weak_ptr. So basically, a weak pointer can have the object it references go away at any time.

Onik
  • 19,396
  • 14
  • 68
  • 91
Max
  • 3,824
  • 8
  • 41
  • 62

3 Answers3

41

sp means StrongPointer in Android, the memory that occupied by the pointed object will be freed if the reference count equals to 0. wp means WeakPointer, so if I have a weak pointer, I don't care whether the referenced object is alive or not. It might be used in some cache and comparison scenarios.

First, take a quick look at the sp implementation in StrongPointer.h.

It is simply a wrapper for reference counting. For example,

template<typename T> template<typename U>
sp<T>& sp<T>::operator = (U* other)
{
    if (other) ((T*)other)->incStrong(this);
    if (m_ptr) m_ptr->decStrong(this);
    m_ptr = other;
    return *this;
}

If you create a Strong Pointer by sp<IBinder> strongPointer, the m_ptr is the referenced object. As you can see in the source code, the sp template only represents a strong pointer so that system won't free the memory as long as I hold this sp. It doesn't maintain a reference counter. The counter is maintained in RefBase class. And in order to use the StrongPointer, your obj need to be an instance of RefBase.

RefBase class maintains both strong reference counter and weak reference counter, the only difference is the referenced object will be freed if the strong counts to 0. Moreover, for an object managed by Refbase, it may referenced by some Strong Pointers and Weak Pointers simultaneously.

You can see a widely uses of StrongPointers in Android framework, most of them are on IBinder object, a native binder object can passed through different processes. Different processes can hold strong pointers to a same object, the object won't be revoked by system as long as one process are still holding the pointer.

StarPinkER
  • 14,081
  • 7
  • 55
  • 81
  • Why doesn't the class `sp` maintain the reference count like how `std::shared_pointer` does? What's the advantage of splitting up the responsibilities like this? – Bob Feb 09 '17 at 16:23
  • @Adrian for `std::shared_ptr` it's actually an inner class which holds the reference count; the shared_ptr holds a pointer to that inner class and copies that pointer. (for the most part) – Paul Stelian May 01 '19 at 16:58
15

Android is meant to be programmed in Java, not C. Any documentation from the Android team would reference that language. In Java there are strong and weak references. A weak reference doesn't stop the garbage collector from cleaning it up, a strong reference does. They're used for caching on some OSes, but on Android as of 3.0 holding only weak references to an object means it will be collected immediately.

C has no equivalent of a weak reference, as it has no garbage collection.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • 6
    Actually I am programming android's kernel so no Java, thanks anyway. – Max Mar 18 '13 at 20:54
  • 5
    Then you should not be interested in Weak or Strong references :-) – fedepaol Mar 18 '13 at 20:56
  • @fedepaol Thank you, but I'm reading android's kernel code and understanding those things is essential. – Max Mar 18 '13 at 20:57
  • 7
    Ok, you should tell us that- less than .1% of people who ask Android questions are working on AOSP, they mean user level android. So yes, strong and weak pointers are different smart pointer implementations and do about the same thing- when a pointer goes out of scope, so long as at least one strong pointer references it it will not be freed. If only weak pointers (or nothing) references it will be. The check is done whenever a strong or weak reference to it is descoped. – Gabe Sechan Mar 18 '13 at 20:59
  • 4
    @crazyfffan I think we are all misunderstanding your question. Strong and weak references are only of relevance in Java. There is no connection with the kernel. You could run ACME Corps Best Ever Mobile Operating System programmed in Pasvasicoboltran on your kernel and it would make no difference. The kernel has no knowledge of user land. – Simon Mar 18 '13 at 20:59
  • 1
    @Simon dig in to android's kernel and you'll see thousands of `sp` and `wp`. Take this as an example: http://www.androidenea.com/2010/03/share-memory-using-ashmem-and-binder-in.html I don't see why you guys raise the Java problem here, basically I am working with the kernel and Java is something out of scope. – Max Mar 18 '13 at 21:02
  • @GabeSechan I see, so if I have 10 weak pointers referencing the same object, and one of those 10 goes out of scope, the object will be destroyed? Whereas with strong pointers, only when all 10 of them go out of scope will the object be destroyed? – Max Mar 18 '13 at 21:13
  • 7
    Yes, almost. If all you have is 10 weak pointers, it would probably have gone out of scope already, when the last strong pointer went out of scope. The implementation may allow it to stick around a little while longer if there's spare memory, but it will be chopped if you go into a low memory condition and it doesn't sound like their implementation is that advanced from her quote. And the use of this is still mainly caching- it is roughly equivalent to a boost shared_ptr and boost weak_ptr. So basically, a weak pointer can have the object it references go away at any time. – Gabe Sechan Mar 18 '13 at 21:20
  • 1
    Also, you can develop native applications with the Anroid NDK. Don't assume people are asking about Java just because they are working on Android. – Bjarke Freund-Hansen Nov 06 '13 at 11:56
  • Java has soft references which are like weak pointers (objects can be collected even with the soft reference being reachable), but objects pointed to by soft references will ONLY be collected if there is memory pressure. – Paul Stelian May 01 '19 at 16:57
2

This is a nice post discussing the difference between regular reference ( or "StrongReference" ), SoftReferences, WeakReferences, and even PhantomReferences in Java, enjoy: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references

Emil Davtyan
  • 13,808
  • 5
  • 44
  • 66