【问题标题】:What are strong pointers and weak pointers什么是强指针和弱指针
【发布时间】:2013-03-07 08:54:15
【问题描述】:

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

当有强指针时,对象会一直存在;它是 最后一个被释放后销毁。弱者所能做的一切 指针是比较并试图提升为强指针; 如果没有其他强指针,后者将失败 对象。

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

更新:

谢谢大家,不过我特意问的是android的内核spwp,和Java的引用完全没有关系。

基本上我正在尝试在这里破解密码http://www.androidenea.com/2010/03/share-memory-using-ashmem-and-binder-in.html 而且不是很懂spwp的用法

更新:

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

强指针和弱指针是不同的智能指针实现 做同样的事情——当指针超出范围时,这么久 因为至少有一个强指针引用它,所以它不会被释放。如果 只有弱指针(或什么都没有)引用它。支票是 每当对它的强或弱引用被取消时就完成。

如果我有 10 个引用同一个对象的弱指针,并且其中一个 那10个超出范围,对象会被销毁吗?而随着 强指针,只有当所有 10 个都超出范围时 对象被销毁?

是的,差不多。如果你只有 10 个弱指针,它可能会 已经超出范围,当最后一个强指针熄灭时 的范围。该实现可能允许它停留一点 如果有空闲内存则更长,但如果你去它会被砍掉 进入低记忆状态,听起来不像他们的 实施比她的报价先进。而这个的用途是 仍然主要是缓存——它大致相当于一个 boost shared_ptr 并提升weak_ptr。所以基本上,弱指针可以拥有对象 它的引用随时消失。

【问题讨论】:

  • +1 表示努力解释这个概念

标签: c android-source android-binder


【解决方案1】:

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

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

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

【讨论】:

  • 为什么sp 类不像std::shared_pointer 那样维护引用计数?这样分权有什么好处?
  • @Adrian for std::shared_ptr 它实际上是一个包含引用计数的内部类; shared_ptr 持有指向该内部类的指针并复制该指针。 (大部分)
【解决方案2】:

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

【解决方案3】:

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

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

【讨论】:

  • 其实我正在编写android的内核,所以没有Java,谢谢。
  • 那么你不应该对弱或强引用感兴趣:-)
  • 好吧,你应该告诉我们,在提出 Android 问题的人中,只有不到 0.1% 的人在使用 AOSP,他们指的是用户级别的 android。所以是的,强指针和弱指针是不同的智能指针实现并且做同样的事情 - 当指针超出范围时,只要至少有一个强指针引用它就不会被释放。如果只有弱指针(或什么都没有)引用它。每当对它的强或弱引用被解除作用域时,就会进行检查。
  • @crazyfffan 我想我们都误解了你的问题。强引用和弱引用仅在 Java 中相关。与内核没有任何联系。你可以在你的内核上运行用 Pasvasicoboltran 编写的 ACME Corps Best Ever Mobile Operating System,它不会有任何区别。内核不知道用户空间。
  • 是的,差不多。如果您只有 10 个弱指针,那么当最后一个强指针超出范围时,它可能已经超出范围。如果有空闲内存,该实现可能允许它停留一段时间,但如果您进入低内存条件,它将被切断,并且听起来他们的实现不像她引用的那样先进。而这个的使用还是主要是缓存——大致相当于一个boost shared_ptr和boostweak_ptr。所以基本上,弱指针可以让它引用的对象随时消失。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 2011-05-19
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多