如何通过boost bimap查找内存占用
How to find the memory take by boost bimap
我有一个boost bimap
#include <iostream>
#include <utility>
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
namespace bimaps = boost::bimaps;
typedef boost::bimap<bimaps::set_of<unsigned long long int>,
bimaps::multiset_of<unsigned long long int > > bimap_reference;
typedef bimap_reference::value_type position;
bimap_reference numbers;
int main()
{
numbers.insert(position(12345689, 1000000000));
numbers.insert(position(23456789, 8000000000));
return 0;
}
我有大约 180000000 个条目。理论上它应该占用 ~2.7GB 的 space (180000000*8*2 = 2880000000 字节 = 2880000000/ 1024*1024*1024 = ~2.7GB )。现在我想找到 boost bimap
拍摄的实际 space,我该怎么做。
就像您提到的问题下的评论一样,您可以重载 new
和 delete
运算符来跟踪内存分配和释放。 this 文章的 全局替换 部分下的示例显示了一个非常简单的示例:
void* operator new(std::size_t sz) {
std::printf("global op new called, size = %zu\n", sz);
return std::malloc(sz);
}
void operator delete(void* ptr) noexcept {
std::puts("global op delete called");
std::free(ptr);
}
此示例的唯一问题是您无法确定释放了多少内存。要解决此问题,请查看 accepted answer of How to track memory allocations in C++ (especially new/delete) 问题。
上述答案中的示例使用 std::map
和自定义分配器来存储已分配内存块的地址和大小。在 delete
运算符重载中,它删除具有指定地址的元素。几乎无需修改即可满足您的要求:
#include <map>
template<typename T>
struct MemoryMapAllocator : std::allocator<T> {
typedef typename std::allocator<T>::pointer pointer;
typedef typename std::allocator<T>::size_type size_type;
template<typename U> struct rebind { typedef MemoryMapAllocator<U> other; };
MemoryMapAllocator() {}
template<typename U>
MemoryMapAllocator(const MemoryMapAllocator<U>& u) : std::allocator<T>(u) {}
pointer allocate(size_type size, std::allocator<void>::const_pointer = 0) {
void* p = std::malloc(size * sizeof(T));
if(p == 0)
throw std::bad_alloc();
return static_cast<pointer>(p);
}
void deallocate(pointer p, size_type) {
std::free(p);
}
};
typedef std::map<void*, std::size_t, std::less<void*>,
MemoryMapAllocator<std::pair<void* const, std::size_t>>> MemoryMap;
MemoryMap& getMemoryMap() {
static MemoryMap memMap;
return memMap;
}
std::size_t totalAllocatedMemory() {
std::size_t sum = 0;
for(auto& e : getMemoryMap())
sum += e.second;
return sum;
}
void* operator new(std::size_t size) {
void* mem = std::malloc(size == 0 ? 1 : size);
if(mem == 0)
throw std::bad_alloc();
getMemoryMap()[mem] = size;
return mem;
}
void operator delete(void* mem) {
getMemoryMap().erase(mem);
std::free(mem);
}
我有一个boost bimap
#include <iostream>
#include <utility>
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
namespace bimaps = boost::bimaps;
typedef boost::bimap<bimaps::set_of<unsigned long long int>,
bimaps::multiset_of<unsigned long long int > > bimap_reference;
typedef bimap_reference::value_type position;
bimap_reference numbers;
int main()
{
numbers.insert(position(12345689, 1000000000));
numbers.insert(position(23456789, 8000000000));
return 0;
}
我有大约 180000000 个条目。理论上它应该占用 ~2.7GB 的 space (180000000*8*2 = 2880000000 字节 = 2880000000/ 1024*1024*1024 = ~2.7GB )。现在我想找到 boost bimap
拍摄的实际 space,我该怎么做。
就像您提到的问题下的评论一样,您可以重载 new
和 delete
运算符来跟踪内存分配和释放。 this 文章的 全局替换 部分下的示例显示了一个非常简单的示例:
void* operator new(std::size_t sz) {
std::printf("global op new called, size = %zu\n", sz);
return std::malloc(sz);
}
void operator delete(void* ptr) noexcept {
std::puts("global op delete called");
std::free(ptr);
}
此示例的唯一问题是您无法确定释放了多少内存。要解决此问题,请查看 accepted answer of How to track memory allocations in C++ (especially new/delete) 问题。
上述答案中的示例使用 std::map
和自定义分配器来存储已分配内存块的地址和大小。在 delete
运算符重载中,它删除具有指定地址的元素。几乎无需修改即可满足您的要求:
#include <map>
template<typename T>
struct MemoryMapAllocator : std::allocator<T> {
typedef typename std::allocator<T>::pointer pointer;
typedef typename std::allocator<T>::size_type size_type;
template<typename U> struct rebind { typedef MemoryMapAllocator<U> other; };
MemoryMapAllocator() {}
template<typename U>
MemoryMapAllocator(const MemoryMapAllocator<U>& u) : std::allocator<T>(u) {}
pointer allocate(size_type size, std::allocator<void>::const_pointer = 0) {
void* p = std::malloc(size * sizeof(T));
if(p == 0)
throw std::bad_alloc();
return static_cast<pointer>(p);
}
void deallocate(pointer p, size_type) {
std::free(p);
}
};
typedef std::map<void*, std::size_t, std::less<void*>,
MemoryMapAllocator<std::pair<void* const, std::size_t>>> MemoryMap;
MemoryMap& getMemoryMap() {
static MemoryMap memMap;
return memMap;
}
std::size_t totalAllocatedMemory() {
std::size_t sum = 0;
for(auto& e : getMemoryMap())
sum += e.second;
return sum;
}
void* operator new(std::size_t size) {
void* mem = std::malloc(size == 0 ? 1 : size);
if(mem == 0)
throw std::bad_alloc();
getMemoryMap()[mem] = size;
return mem;
}
void operator delete(void* mem) {
getMemoryMap().erase(mem);
std::free(mem);
}