webkit内存管理1:智能指针

来源:互联网 发布:淘宝如何申请信用卡 编辑:程序博客网 时间:2024/05/01 22:59

转载请注明出处:http://blog.csdn.net/awebkit


对于 c/c++ 开发来说,内存管理是一个头疼的问题。那么, WebKit 是如何来管理内存的呢?

首先,我们来学习一下 WebKit 中的智能指针,这是内存管理一个很基础的部分。

在小项目中,大家遵循内存一个申请对应一个释放的原则,基本能解决内存管理问题。但是对于一个大项目,简单靠程序员的自觉性是不够的,因此, WebKit 借鉴 c++ 的智能指针,引入了自己的智能指针管理类 RefPtr PassRefPtr等。由于我本身对 c++ 的智能指针不是很熟悉,因此,不好比较。不过,对于 WebKit 的这些智能指针,我得说,他们足够简单有效。

RefPtr

RefPtr 是一个模板,参数类需要有 ref 和 deref 函数,而 RefCounted 类实现了这两个接口,所以参数类大多继承于 RefCounted 。

如果不使用 RefPtr ,使用裸指针,则代码大概是这样的

// example, not preferred styleclass Document {    ...    Title* m_title;}Document::Document()    : m_title(0){}Document::~Document(){    if (m_title)        m_title->deref();}void Document::setTitle(Title* title){    if (title)        title->ref();    if (m_title)        m_title->deref();    m_title = title;}

是不是很烦?还容易忘记,写错等。

有了 RefPtr 的代码大概是这样的
// example, not preferred style class Document {    ...    RefPtr<Title> m_title;}void Document::setTitle(Title* title){    m_title = title;}

但是,单独使用 RefPtr 会造成引用计数的震荡

// example, not preferred style; should use RefCounted and adoptRef (see below) RefPtr<Node> createSpecialNode(){    RefPtr<Node> a = new Node;    a->setSpecial(true);    return a;}RefPtr<Node> b = createSpecialNode();

解释:
For purposes of this discussion, lets assume that the node object starts with a reference count of 0 (more on this later). When it’s assigned to a, the reference count is incremented to 1. The reference count is incremented to 2 to create the return value, then decremented back to 1 when a is destroyed. Then the reference count is incremented to 2 to create b, and then decremented back to 1 when the return value of createSpecialNode is destroyed.

总之,你看到引用计数是在不断的变化。为了解决这个问题,引入了 PassRefPtr

PassRefPtr

PassRefPtr 和 RefPtr 在一点上有所不同。在赋值时,原指针设置为0。整个操作不涉及引用计数的改变

// example, not preferred style; should use RefCounted and adoptRef (see below)PassRefPtr<Node> createSpecialNode(){    PassRefPtr<Node> a = new Node;    a->setSpecial(true);    return a;}RefPtr<Node> b = createSpecialNode();

解释:
The node object starts with a reference count of 0. When it’s assigned to a, the reference count is incremented to 1. Then a gets set to 0 when the return value PassRefPtr is created. Then the return value is set to 0 when b is created.

但是这样可能会引起别的问题
// warning, will dereference a null pointer and will not work static RefPtr<Ring> g_oneRingToRuleThemAll;void finish(PassRefPtr<Ring> ring){    g_oneRingToRuleThemAll = ring;    ...    ring->wear();}

ring 已经为0了,还操作?

所以,要混合操作:建议参数和返回值用 PassRefPtr ,local 用 RefPtr
static RefPtr<Ring> g_oneRingToRuleThemAll;void finish(PassRefPtr<Ring> prpRing){    RefPtr<Ring> ring = prpRing;    g_oneRingToRuleThemAll = ring;    ...    ring->wear();}

其他注意事项


1. 裸指针通过 adoptRef 传递指针到 RefPtr 进行管理
// warning, requires a pointer that already has a refRefPtr<Node> node = adoptRef(rawNodePointer);

2. 对象创建后,传给 RefPtr 或 PassRefPtr ,引用计数记为1。所以一般是static create创建对象,而构造函数为 private 

3. OwnPtr 提供了一种更普遍的类的管理(指针传递),而 RefPtr 用于引用计数类的管理。 OwnPtr 在离开作用域的时候,自动销毁对象。



参考:
http://www.webkit.org/coding/RefPtr.html






原创粉丝点击