2017-07-15 54 views
0

我有一個boost bimap如何找到內存利用由升壓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; 
} 

我有大約1.8項。理論上應該佔用〜2.7GB的空間(180000000 * 8 * 2 = 2880000000字節= 2880000000/1024 * 1024 * 1024 =〜2.7GB)。現在我想找到boost bimap所用的實際空間,我該怎麼做。

+0

您可能超載全球'new'和'delete'運營商,並轉發給'malloc',但加入了計數器跟蹤分配的字節。在填充「bimap」之前重置計數,填充它並打印字節數。 –

+0

@MatteoItalia,謝謝,一個例子會非常有幫助。 – AwaitedOne

回答

1

就像您提到的問題中的意見一樣,您可以重載newdelete運算符來跟蹤內存分配和釋放。根據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); 
} 

這個例子,你不能確定有多少內存被釋放,唯一的問題。要解決此問題,請查看How to track memory allocations in C++ (especially new/delete)accepted answer問題。

上述答案中的示例使用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); 
} 

Live Demo