SGI空间配置器
来源:互联网 发布:安卓编程用什么软件 编辑:程序博客网 时间:2024/05/22 06:40
STL allocater 决定两阶段操作区分开来。内存配置操作由 alloc:allocate()负责,内存操作由alloc:deallocate()负责,对象构造操作由::construct()负责,对象析构操作由::destory()负责。
#include<stl_alloc.h>//包含内存空间的配置和释放#include<stl_construct.h>// 负责 对象内容的构造和析构
构造和析构基本工具:construct()和destroy()
#include <new.h> //要想使用 palcement new 能够在一段内存空间构造对象。template <class _T1, class _T2> inline void _Construct(_T1* __p, const _T2& __value) { new ((void*) __p) _T1(__value); //将value设定到地址p指向的内存上}/***这叫placenew,在指针p所指向的内存空间创建一个类型为T1的对象。调用的构造函数接受一个类型为const T2&(或其他兼容类型)的参数new placement 你可以简单的理解为C中的realloc,就是在已有空间的基础上,重新分配一个空间,可以不破坏原来数据,也可以把数据全部用新值覆盖 ****///new一段p指向的内存template <class _T1>inline void _Construct(_T1* __p) { new ((void*) __p) _T1(); }//以下是destory()第一个版本接受一个指针 调用析构函数 将p所指向的空间析构掉。template <class _Tp>inline void _Destroy(_Tp* __pointer) { __pointer->~_Tp(); }//以下是destory()第二版本接受两个迭代器此函数设法找出 元素的数值型别,进而利用__type_traits//求取最合适的措施析构对象。template <class _ForwardIterator>inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) { __destroy(__first, __last, __VALUE_TYPE(__first));}//判断元素类型 是否有trivial destructor 有就是 true_type,没有就是false_typetemplate <class _ForwardIterator, class _Tp>inline void __destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*){ typedef typename __type_traits<_Tp>::has_trivial_destructor _Trivial_destructor; __destroy_aux(__first, __last, _Trivial_destructor());}//如果是 non-trivial destructor 则调用destory第一个版本template <class _ForwardIterator>void__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type){ for ( ; __first != __last; ++__first) destroy(&*__first);}template <class _ForwardIterator> inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}----------------------------------------------------------------------/*如果用户不定义析构函数,而是用系统自带的,则说明,析构函数基本没有什么用(但默认会被调用)我们称之为trivial destructor。反之,如果特定定义了析构函数,则说明需要在释放空间之前做一些事情,则这个析构函数称为non-trivial destructor。如果某个类中只有基本类型的话是没有必要调用析构函数的,delelte p的时候基本不会产生析构代码。在STL中空间配置时候destory()函数会判断要释放的迭代器的指向的对象有没有 trivial destructor(STL中有一个 has_trivial_destructor函数,很容易实现检测)放,如果有trivial destructor则什么都不做,如果没有即需要执行一些操作,则执行真正的destory函数。destory()有两个版本,第一个版本接受一个指针,准备将该指针所指之物析构掉,第二个版本接受first和last两个迭代器,准备将[first,last]范围内的所有对象析构掉。我们不知道这个范围有多大,万一很大,而每个对象的析构函数都无关痛痒,那么一次次调用这些析构函数,对效率是一种伤害,因此这里首先利用value_type()获得迭代器所指对象的类别,再利用_type_traits<T>判断该型别的析构函数是否无关痛痒,若是(_true_type),则什么也不做就结束,若否(_false_type),这才以循环的方式巡访整个范围,并在循环中每经历一个对象就调用第一个版本的destory()。**/---------------------------------------------------------------------//以下是destory第二个版本的特化版。inline void _Destroy(char*, char*) {}inline void _Destroy(int*, int*) {}inline void _Destroy(long*, long*) {}inline void _Destroy(float*, float*) {}inline void _Destroy(double*, double*) {}#ifdef __STL_HAS_WCHAR_Tinline void _Destroy(wchar_t*, wchar_t*) {}#endif /* __STL_HAS_WCHAR_T */// --------------------------------------------------// Old names from the HP STL.__STL_END_NAMESPACE
空间的配置和释放。std::alloc
对象构造前的空间配置和对象构造后的空间释放,由
其设计如下:
(1)向system heap要求空间
(2)考虑多线程状态
(3)考虑内存不足的应变措施
(4)考虑过多小型区块的内存碎片问题
考虑到SGI设计了双层配置器,第一层配置器直接使用malloc()和free(),第二层配置器则视情况超过128bytes 则调用第一级配置器;小于128bytes 便采用复杂的 内存池 整理方式。
第一级配置器 _ _malloc_alloc_template 剖析
// 以下是第一級配置器。// 注意,無「template型別參數」。「非型別參數」inst完全沒派上用場。template <int inst>class __malloc_alloc_template {private:static void *oom_malloc(size_t);static void *oom_realloc(void *, size_t);#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG static void (* __malloc_alloc_oom_handler)();#endifpublic:static void * allocate(size_t n){ void *result = malloc(n); // 第一級配置器直接使用 malloc() if (0 == result) result = oom_malloc(n); return result;}static void deallocate(void *p, size_t /* n */){ free(p); // 第一級配置器直接使用 free()}static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz){ void * result = realloc(p, new_sz); // 第一級配置器直接使用 realloc() if (0 == result) result = oom_realloc(p, new_sz); return result;}// 以下類似 C++ 的 set_new_handler().//这个函数的机制是,你可以要求系统在内存配置无法被满足时,调用一个你所指定的函数。 new_handler解决内存不足的特有模式。static void (* set_malloc_handler(void (*f)()))(){ void (* old)() = __malloc_alloc_oom_handler; __malloc_alloc_oom_handler = f; return(old);}};// malloc_alloc out-of-memory handling#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUGtemplate <int inst>void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;#endiftemplate <int inst>void * __malloc_alloc_template<inst>::oom_malloc(size_t n){ void (* my_malloc_handler)(); void *result; for (;;) { // 不斷嘗試釋放、配置、再釋放、再配置… my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); // 呼叫處理常式,企圖釋放記憶體。 result = malloc(n); // 再次嘗試配置記憶體。 if (result) return(result); }}template <int inst>void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n){ void (* my_malloc_handler)(); void *result; for (;;) { // 不斷嘗試釋放、配置、再釋放、再配置… my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); // 呼叫處理常式,企圖釋放記憶體。 result = realloc(p, n); // 再次嘗試配置記憶體。 if (result) return(result); }}typedef __malloc_alloc_template<0> malloc_alloc;
阅读全文
0 0
- SGI空间配置器
- SGI-STL空间配置器
- 【STL】SGI空间配置器 Allocator
- SGI STL的空间配置器alloc
- SGI STL 之空间配置器
- SGI特殊空间配置器std::alloc
- SGI版的空间配置器
- SGI STL空间配置器-第一级空间配置器
- SGI STL空间配置器-第二级空间配置器
- SGI STL第二级空间配置器空间释放函数deallocate
- SGI STL空间配置器(STL源码剖析):
- STL一级空间配置器(SGI版本)
- SGI STL 空间配置器(allocator)源码剖析
- SGI STL V3.2 源码剖析 - 空间配置器
- SGI STL空间配置器(STL源码剖析)
- SGI STL空间配置器和内存池
- SGI STL 空间配置器(allocator)源码剖析
- SGI STL 第二级空间配置器函数 allocate()
- LoadRunner学习笔记——Day4
- QT Json 解析
- Hello the curel world!
- git基本使用场景及命令
- linux下Android开机动画制作
- SGI空间配置器
- elasticsearch及head插件安装
- Apk瘦身指南
- spring框架学习(二)依赖注入
- 常用的正则表达式
- SylixOS 中断系统分析
- 单链表有序插入
- ASP.NET开发常用的几个方法
- 脚本练习-Script.sh批量创建用户