网站一站 手机微信600 900,绍兴网站建设解决方案,app定制制作价格,网站的ftp地址是什么目录
一、对象池简介
1.1 池化技术
1.2 什么是对象池
1.3 对象池分配策略
二、C new和delete运算符重载
三、实现一个对象池框架
3.1 策略接口
四、实现几种对象池的分配策略
4.1 数组策略
4.2 堆策略
编辑
4.3 栈策略
4.4 区块策略 一、对象池简介
1.1 池化技…目录
一、对象池简介
1.1 池化技术
1.2 什么是对象池
1.3 对象池分配策略
二、C new和delete运算符重载
三、实现一个对象池框架
3.1 策略接口
四、实现几种对象池的分配策略
4.1 数组策略
4.2 堆策略
编辑
4.3 栈策略
4.4 区块策略 一、对象池简介
1.1 池化技术
线程池、连接池、内存池 池化技术共同点
提前创建资源以备不时之需时重复利用极致的提升性能。 由于在实际应用里分配内存、创建进程、线程都会涉及到一些系统调用系统调用需要导致程序从用户态切换到内核态是非常耗时的操作。因此当程序中需要频繁的进行内存申请释放进程、线程创建销毁等操作时通常会使用内存池、进程池、线程池等技术来提升程序的性能。 1.2 什么是对象池
对象池简介
对象池的实现和内存池的实现原理很像:都是-开始申请大内存空间, 然后把大内存分配成小内存空间当需要使用的时候直接分配使用,不再向系统申请内存空间也不直接释放内存空间。使用完之后都是放回池子里。 注意
对象池其实就是一种特殊的内存池仅分配固定大小的内存。 1.3 对象池分配策略
● 基于数组的策略
● 基于堆的策略
● 基于栈的策略
● 基于区块的策略
课程里我们会实现以上几种对象池的分配策略从最简单的数组策略到比较复杂的区块策略。每种策略都有各自的特点和适用场景。 二、C new和delete运算符重载
class A
{
public:void * operator new(size_t n){std::cout A new std::endl; return ::malloc(n);}void operator delete(void * p){std::cout A delete std::endl;::free(p);}
}; 三、实现一个对象池框架 3.1 策略接口
template typename T
class Allocator {
public:virtual T * allocate() 0;virtual void deallocate(T * p) 0;
};
策略接口函数
allocate分配内存
deallocate回收内存 现在创建和析构对象不需要用new和free了而是用对象池的创建和析构函数。 // a.h#pragma once
#include iostream
#include object_pool.h
#include malloc_allocator.husing namespace huan::object;class A
{
private:typedef ObjectPoolA, MallocAllocatorA ObjectPool;static ObjectPool pool;
public:A(){std::cout A construct std::endl;}~A(){std::cout A destruct std::endl;}void * operator new(size_t n){std:: cout A new std::endl;return pool.allocate(n);}void operator delete(void * p){std::cout A delete std::endl;pool.deallocate(p);}
};A::ObjectPool A::pool; // object_pool.h#pragma once#include stdexceptnamespace huan
{namespace object{template typename T, typename Allocatorclass ObjectPool{public:ObjectPool() default;~ObjectPool() default;void * allocate(size_t n){if (sizeof(T) ! n)throw std::bad_alloc();return m_allocator.allocate();}void deallocate(void * p){m_allocator.deallocate(static_castT *(p));}private:Allocator m_allocator;};}
} // malloc_allocator.h#pragma once#include allocator.hnamespace huan
{namespace object{template typename Tclass MallocAllocator : public AllocatorT{public:MallocAllocator() default;~MallocAllocator() default;virtual T * allocate(){auto p ::malloc(sizeof(T));return reinterpret_castT *(p);}virtual void deallocate(T * p){::free(p);}};}
} // allocator.h#pragma oncenamespace huan
{namespace object{template typename Tclass Allocator{public:virtual T * allocate() 0;virtual void deallocate(T * p) 0;};}
} 四、实现几种对象池的分配策略
4.1 数组策略 #include src/a.hint main()
{A * arr[max_size] { nullptr };for (int i 0; i max_size; i){A * a new A();arr[i] a;}for (int i 0; i max_size; i){delete arr[i];}return 0;
} #pragma once#include allocator.hnamespace huan
{namespace object{template typename T, int Nclass ArrayAllocator : public AllocatorT{public:ArrayAllocator(){for (int i 0; i N; i){m_used[i] false;}}~ArrayAllocator() default;virtual T * allocate(){for (int i 0; i N; i){if (!m_used[i]){m_used[i] true;return reinterpret_castT *(m_data[sizeof(T) * i]);}}// 如果没找到throw std::bad_alloc();}virtual void deallocate(T * p){auto i ((unsigned char *)p - m_data) / sizeof(T);m_used[i] false;}private:unsigned char m_data[sizeof(T) * N];bool m_used[N];};}
}
注意基于数组的时间复杂度高 O(n) 4.2 堆策略 使用大根堆heap第一个位置总是空闲的。在插入一个对象后堆会重新把一个没有使用的位置放到第一位 // heap_allocator.h#include algorithm
#include allocator.hnamespace huan
{namespace object{template typename T, int Nclass HeapAllocator : public AllocatorT{public:enum State{FREE 1,USED 0,};struct Entry{State state; // 状态T * p; // 对象指针bool operator (const Entry other) const{return state other.state;}};HeapAllocator(){m_available N;for (int i 0; i N; i){m_entry[i].state FREE; // 未使用m_entry[i].p reinterpret_castT *(m_data[sizeof(T) * i]);}// 调用生成大堆的算法std::make_heap(m_entry, m_entry N);}~HeapAllocator() default;virtual T * allocate(){if (m_available 0)throw std::bad_alloc();Entry e m_entry[0];std::pop_heap(m_entry, m_entry N);m_available--;m_entry[m_available].state USED;m_entry[m_available].p nullptr;return e.p;}virtual void deallocate(T * p){if (p nullptr || m_available N)return;m_entry[m_available].state FREE;m_entry[m_available].p reinterpret_castT *(p);m_available;std::push_heap(m_entry, m_entry N);}private:unsigned char m_data[sizeof(T) * N];Entry m_entry[N];int m_available;};}
}
时间复杂度 O(log n) 4.3 栈策略
4.4 区块策略