shared_ptr 和 shared_array 为引用计数器分配内存

Posted

技术标签:

【中文标题】shared_ptr 和 shared_array 为引用计数器分配内存【英文标题】:shared_ptr and shared_array allocate memory for reference counter 【发布时间】:2013-07-08 14:43:03 【问题描述】:

在分析我的应用程序后,我发现mallocs 太多了。我很惊讶shared_ptrshared_array 为引用计数分配了内存。除此之外,封装引用计数的对象包含两个计数uses_countweak_count 以及指向虚拟表的指针。对我来说,当我只需要一个简单的引用计数类时,这似乎有点过头了。有什么方法可以调整shared_ptrshared_array 以实现更简单的方案?无需额外致电malloc,只需一个柜台:uses_count。或者也许在 STL 或 Boost 中的某个地方有一个更简单的类?

【问题讨论】:

使用make_shared 这正是我不使用 shared_ptr 等的原因。特别是,因为这意味着我不会被允许从普通指针制作智能指针,迫使我使用额外的级别间接等。我知道的引用计数的唯一干净方法是:在基类中实现它并从中派生所有内容。添加一个智能指针模板,你就有了一些可用的东西,没有任何微妙的问题。恕我直言,STL 方法太过分了。 @cmaster 已经为您完成了基类中的实现:boost::intrusive_ptr ;-) 我想知道为什么 ref 计数器仍然位于默认构造函数中。这应该只在重置时分配,或者从指针构造时分配。这会损失很多性能。我觉得这纯粹是为了“ifless 编程”,或者说“特殊情况不足以打破规则”,但这在这里很糟糕。 【参考方案1】:

如果您使用boost::make_shared,该函数将在一次调用new 时为引用计数器和对象分配内存。 弱引用的额外计数器应该不是什么大问题,因为它只是额外的 4 或 8 个字节不会受到伤害。 如果分析显示shared_ptr 的实现仍然是您的应用程序的瓶颈,请考虑使用boost::intrusive_ptr。还要寻找通过引用而不是通过值传递 shared_ptrs ,或者如果需要副本则通过移动它们来传递它们。当然,如果你可以使用unique_ptr,你应该更喜欢shared_ptrs

【讨论】:

谢谢! intrusive_ptr 是我要找的。​​span> 【参考方案2】:
    shared_ptr<A> sp( new A(), A_Deleter(), My_allocator<A>() );

    template <typename T> 
    class My_allocator 
     
        ...
        T * allocate(const size_t n) const 
            return singleton_pool<T,sizeof(T)>::malloc();
        
        ....
    ;

我认为您抱怨内存使用问题。我发现 std 分配器可以解决它;

【讨论】:

以上是关于shared_ptr 和 shared_array 为引用计数器分配内存的主要内容,如果未能解决你的问题,请参考以下文章

如何将原始数据附加到 boost::shared_array<char>?

将字符串存储在 mmap 共享数组中? (C)

`shared_ptr::use_count() == 0` 和 `shared_ptr::get() != nullptr` 是不是可能?

C++ 11 创建和使用 shared_ptr

shared_ptr和动态数组

使用相同的函数但重载不同的 std::tr1::shared_ptr<T> 和 std::shared_ptr<T>