STL的默认allocator

    很早之前看过SGI的默认allocator,是采用了定常内存池分配的一种策略,之后一直以为gcc自带的STL应该也是如此般实现。最近同事和同事在讨论vector的reserve的时候,又讨论到这个问题,我仍然信誓旦旦的解释一遍关于这个默认allocator的实现。过后自己又略又有不安,gcc自带的STL确实是这样的么?于是赶紧翻了一下源码看了一下,最后发现结果出乎我意料,如下:

template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>

  template<typename _Tp>
    class allocator: public __glibcxx_base_allocator<_Tp>
    {
   public:
      typedef size_t     size_type;
      typedef ptrdiff_t  difference_type;
      typedef _Tp*       pointer;
      typedef const _Tp* const_pointer;
      typedef _Tp&       reference;
      typedef const _Tp& const_reference;
      typedef _Tp        value_type;

      template<typename _Tp1>
        struct rebind
        { typedef allocator<_Tp1> other; };

      allocator() throw() { }

      allocator(const allocator& __a) throw()
      : __glibcxx_base_allocator<_Tp>(__a) { }

      template<typename _Tp1>
        allocator(const allocator<_Tp1>&) throw() { }

      ~allocator() throw() { }

      // Inherit everything else.
    };

    很明显,这里默认的allocator只是调用glibc中的operator new和operator delete而已。在这里,我的gcc版本是4.1.0。为什么会出现这样的情况呢?
    google了一下,有看到一些解答说是gcc 3.*之前的版本确实是默认使用的内存池的,而到了 4.*之后才去掉的。总说纷纭,还是上gcc的online doc找找答案了,最后终于发现了解答:

Selecting Default Allocation Policy

It's difficult to pick an allocation strategy that will provide maximum utility, without excessively penalizing some behavior. In fact, it's difficult just deciding which typical actions to measure for speed.

Three synthetic benchmarks have been created that provide data that is used to compare different C++ allocators. These tests are:

  1. Insertion.

    Over multiple iterations, various STL container objects have elements inserted to some maximum amount. A variety of allocators are tested. Test source for sequence andassociative containers.

  2. Insertion and erasure in a multi-threaded environment.

    This test shows the ability of the allocator to reclaim memory on a pre-thread basis, as well as measuring thread contention for memory resources. Test source here.

  3. A threaded producer/consumer model.

    Test source for sequence and associative containers.

The current default choice for allocator is __gnu_cxx::new_allocator.

Disabling Memory Caching

In use, allocator may allocate and deallocate using implementation-specified strategies and heuristics. Because of this, every call to an allocator object's allocate member function may not actually call the global operator new. This situation is also duplicated for calls to the deallocate member function.

This can be confusing.

In particular, this can make debugging memory errors more difficult, especially when using third party tools like valgrind or debug versions of new.

There are various ways to solve this problem. One would be to use a custom allocator that just called operators new and delete directly, for every allocation. (Seeinclude/ext/new_allocator.h, for instance.) However, that option would involve changing source code to use a non-default allocator. Another option is to force the default allocator to remove caching and pools, and to directly allocate with every call of allocate and directly deallocate with every call of deallocate, regardless of efficiency. As it turns out, this last option is also available.

To globally disable memory caching within the library for the default allocator, merely set GLIBCXX_FORCE_NEW (with any value) in the system's environment before running the program. If your program crashes with GLIBCXX_FORCE_NEW in the environment, it likely means that you linked against objects built against the older library (objects which might still using the cached allocations...).


    同时,还发现了,在gcc构建的时候是可以选择STL的默认allocator的,有一个 enable-libstdcxx-allocator 的构建参数可以指定,详细的信息可以参考这个:http://gcc.gnu.org/onlinedocs/libstdc++/manual/configure.html

    侯JJ在STL源码解析的时候就写了一句话,源码之前,了无秘密。所以,很多时候还是不应该想当然的好,尤其是源码已经摆在那里的时候。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值