33

我对“强指针”和“弱指针”的概念感到困惑。黛安哈克伯恩自己说:

当有强指针时,对象将保留在周围;一旦最后一个被释放,它就会被销毁。使用弱指针所能做的就是比较并尝试提升为强指针;如果对象上没有其他强指针,后者将失败。

这对我来说很不清楚。强指针是否等同于 ( boost::) 共享指针?如果弱指针只是为了尝试将自己提升为强指针,那么弱指针的作用是什么?比如,我们什么时候需要弱指针和强指针?

更新:

谢谢大家,但我是专门询问android的内核spwp,它们与Java的引用完全无关。

基本上我正在尝试破解这里的代码http://www.androidenea.com/2010/03/share-memory-using-ashmem-and-binder-in.html 而且不太了解和的sp使用wp

更新:

实际答案在于接受答案的评论。感谢 Gabe Sechan:

强指针和弱指针是不同的智能指针实现并且做同样的事情——当指针超出范围时,只要至少有一个强指针引用它,它就不会被释放。如果只有弱指针(或什么都没有)引用它。每当对它的强或弱引用被描述时,就会进行检查。

如果我有 10 个引用同一个对象的弱指针,而这 10 个中的一个超出范围,那么该对象会被销毁吗?而使用强指针,只有当它们全部超出范围时,对象才会被销毁?

是的,差不多。如果您只有 10 个弱指针,那么当最后一个强指针超出范围时,它可能已经超出范围。如果有空闲内存,该实现可能允许它停留一段时间,但如果您进入低内存条件,它将被切断,并且听起来他们的实现不像她引用的那样先进。而这个的使用还是主要是缓存——大致相当于一个boost shared_ptr和boostweak_ptr。所以基本上,弱指针可以让它引用的对象随时消失。

4

3 回答 3

39

sp表示Android中的StrongPointer,如果引用计数等于0,则被指向的对象占用的内存将被释放。wp表示WeakPointer,所以如果我有弱指针,我不在乎引用的对象是否活着. 它可能用于某些缓存和比较场景。

首先,快速浏览一下StrongPointer.h中的 sp 实现。

它只是一个引用计数的包装器。例如,

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;
}

如果您通过创建强指针sp<IBinder> strongPointer,则 m_ptr 是被引用的对象。正如你在源代码中看到的,sp 模板只代表一个强指针,因此只要我持有这个sp,系统就不会释放内存。它不维护引用计数器。计数器在RefBase类中维护。为了使用 StrongPointer,你的 obj 需要是 RefBase 的一个实例。

RefBase 类同时维护了强引用计数器和弱引用计数器,唯一的区别是如果强计数为 0,被引用的对象将被释放。此外,对于 Refbase 管理的对象,它可能同时被一些强指针和弱指针引用。

可以看到StrongPointers在Android框架中的应用非常广泛,大部分都在IBinder对象上,一个原生的Binder对象可以通过不同的进程。不同的进程可以持有指向同一个对象的强指针,只要一个进程还持有该指针,系统就不会撤销该对象。

于 2013-03-19T06:05:12.157 回答
14

Android 旨在使用 Java 而非 C 进行编程。Android 团队的任何文档都将引用该语言。在 Java 中,有强引用和弱引用。弱引用不会阻止垃圾收集器清理它,强引用会。它们用于在某些操作系统上进行缓存,但在 Android 3.0 中仅持有对对象的弱引用意味着它将立即被收集。

C 没有弱引用,因为它没有垃圾收集。

于 2013-03-18T20:52:27.187 回答
2

这是一篇很好的文章,讨论了 Java 中的常规引用(或“StrongReference”)、SoftReferences、WeakReferences 甚至PhantomReferences 之间的区别,请欣赏: http ://weblogs.java.net/blog/2006/05/04/understanding-弱引用

于 2013-03-18T20:56:24.220 回答