Boost池最大大小
Boost Pool maximum size
本文关键字:Boost 更新时间:2023-10-16
我使用boost池作为静态内存提供程序,
void func()
{
std::vector<int, boost::pool_allocator<int> > v;
for (int i = 0; i < 10000; ++i)
v.push_back(13);
}
在上面的代码中,我们如何修复池的大小,我的意思是我们知道boost::pool提供作为一个静态内存分配器,但我无法修复这个池的大小,它不断增长,应该有办法限制它的大小。例如,我想要一个只有200块的池,这样我就可以取200块,之后它应该是NULL请告诉我怎么做
我不认为boost池提供了您想要的。实际上,除了对象类型之外,boost::pool_allocator
还有其他4个模板参数:
-
UserAllocator
:定义底层池从系统分配内存的方法(default =boost::default_user_allocator_new_delete
)。 -
Mutex
:允许用户决定在底层singleton_pool(default =boost::details::pool::default_mutex
)上使用的同步类型。 -
NextSize
:该参数的值在底层池创建时传递给底层池,并指定在第一次分配请求中分配的块数量(默认= 32)。 -
MaxSize
:该参数的值在创建时传递给底层池,并指定在任何单个分配请求中分配的最大块数(默认= 0)。
你可能认为MaxSize
正是你想要的,但不幸的是,它不是。boost::pool_allocator
使用基于boost::pool
的底层boost::singleton_pool
, MaxSize
最终将传递给boost::pool<>
的数据成员:max_size
,那么max_size
在boost::pool
中扮演什么角色?让我们来看看boost::pool::malloc()
:
void * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
{ //! Allocates a chunk of memory. Searches in the list of memory blocks
//! for a block that has a free chunk, and returns that free chunk if found.
//! Otherwise, creates a new memory block, adds its free list to pool's free list,
//! returns a free chunk from that block.
//! If a new memory block cannot be allocated, returns 0. Amortized O(1).
// Look for a non-empty storage
if (!store().empty())
return (store().malloc)();
return malloc_need_resize();
}
显然,如果内存块中没有可用的空闲块, boost::pool
会立即分配一个新的内存块。让我们继续深入了解malloc_need_resize()
:
template <typename UserAllocator>
void * pool<UserAllocator>::malloc_need_resize()
{ //! No memory in any of our storages; make a new storage,
//! Allocates chunk in newly malloc aftert resize.
//! returns pointer to chunk.
size_type partition_size = alloc_size();
size_type POD_size = static_cast<size_type>(next_size * partition_size +
math::static_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type));
char * ptr = (UserAllocator::malloc)(POD_size);
if (ptr == 0)
{
if(next_size > 4)
{
next_size >>= 1;
partition_size = alloc_size();
POD_size = static_cast<size_type>(next_size * partition_size +
math::static_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type));
ptr = (UserAllocator::malloc)(POD_size);
}
if(ptr == 0)
return 0;
}
const details::PODptr<size_type> node(ptr, POD_size);
BOOST_USING_STD_MIN();
if(!max_size)
next_size <<= 1;
else if( next_size*partition_size/requested_size < max_size)
next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size);
// initialize it,
store().add_block(node.begin(), node.element_size(), partition_size);
// insert it into the list,
node.next(list);
list = node;
// and return a chunk from it.
return (store().malloc)();
}
从源代码中我们可以看到, max_size
只是与下次向系统请求的块的数量有关,我们只能通过这个参数减慢增加的速度。
但是请注意,我们可以定义底层池从系统中分配内存的方法,如果我们限制从系统中分配的内存大小,池的大小将不会继续增长。这样,boost::pool
似乎是多余的,您可以直接将自定义分配器传递给STL容器。下面是一个自定义分配器的示例(基于此链接),它将内存从堆栈分配到给定的大小:
#include <cassert>
#include <iostream>
#include <vector>
#include <new>
template <std::size_t N>
class arena
{
static const std::size_t alignment = 8;
alignas(alignment) char buf_[N];
char* ptr_;
bool
pointer_in_buffer(char* p) noexcept
{ return buf_ <= p && p <= buf_ + N; }
public:
arena() noexcept : ptr_(buf_) {}
~arena() { ptr_ = nullptr; }
arena(const arena&) = delete;
arena& operator=(const arena&) = delete;
char* allocate(std::size_t n);
void deallocate(char* p, std::size_t n) noexcept;
static constexpr std::size_t size() { return N; }
std::size_t used() const { return static_cast<std::size_t>(ptr_ - buf_); }
void reset() { ptr_ = buf_; }
};
template <std::size_t N>
char*
arena<N>::allocate(std::size_t n)
{
assert(pointer_in_buffer(ptr_) && "short_alloc has outlived arena");
if (buf_ + N - ptr_ >= n)
{
char* r = ptr_;
ptr_ += n;
return r;
}
std::cout << "no memory available!n";
return NULL;
}
template <std::size_t N>
void
arena<N>::deallocate(char* p, std::size_t n) noexcept
{
assert(pointer_in_buffer(ptr_) && "short_alloc has outlived arena");
if (pointer_in_buffer(p))
{
if (p + n == ptr_)
ptr_ = p;
}
}
template <class T, std::size_t N>
class short_alloc
{
arena<N>& a_;
public:
typedef T value_type;
public:
template <class _Up> struct rebind { typedef short_alloc<_Up, N> other; };
short_alloc(arena<N>& a) noexcept : a_(a) {}
template <class U>
short_alloc(const short_alloc<U, N>& a) noexcept
: a_(a.a_) {}
short_alloc(const short_alloc&) = default;
short_alloc& operator=(const short_alloc&) = delete;
T* allocate(std::size_t n)
{
return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
}
void deallocate(T* p, std::size_t n) noexcept
{
a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
}
template <class T1, std::size_t N1, class U, std::size_t M>
friend
bool
operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept;
template <class U, std::size_t M> friend class short_alloc;
};
template <class T, std::size_t N, class U, std::size_t M>
inline
bool
operator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
{
return N == M && &x.a_ == &y.a_;
}
template <class T, std::size_t N, class U, std::size_t M>
inline
bool
operator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
{
return !(x == y);
}
int main()
{
const unsigned N = 1024;
typedef short_alloc<int, N> Alloc;
typedef std::vector<int, Alloc> SmallVector;
arena<N> a;
SmallVector v{ Alloc(a) };
for (int i = 0; i < 400; ++i)
{
v.push_back(10);
}
}
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- C++:如何在CLion IDE中安装Boost
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何在boost beast http请求中设置http头
- Boost Spirit,获取迭代器内部语义动作
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 使用Boost Interprocess创建托管共享内存需要很长时间
- Boost::posix_time::ptime舍入到给定的分钟数
- boost xml parsingl将xml的路径作为变量发送