对象消耗了多少内存
How much memory consumed by my object
我想知道编程的方式来获得由我的用户定义类消耗的内存。下面是类
的声明struct TrieNode {
typedef std::map<char, TrieNode *> ChildType;
std::string m_word;
bool m_visited;
}
我将264061
周围的单词插入到Trie
中。在这之后,当我做sizeof(trieobject)
时,它只显示32
。我如何知道这些数据结构使用了多少确切的内存
我用
valgrind --tool=massif ./myprogram -opt arg1 arg2
ms_print massif.* | less -SR
。本页
的输出示例19.63^ ###
| #
| # ::
| # : :::
| :::::::::# : : ::
| : # : : : ::
| : # : : : : :::
| : # : : : : : ::
| ::::::::::: # : : : : : : :::
| : : # : : : : : : : ::
| ::::: : # : : : : : : : : ::
| @@@: : : # : : : : : : : : : @
| ::@ : : : # : : : : : : : : : @
| :::: @ : : : # : : : : : : : : : @
| ::: : @ : : : # : : : : : : : : : @
| ::: : : @ : : : # : : : : : : : : : @
| :::: : : : @ : : : # : : : : : : : : : @
| ::: : : : : @ : : : # : : : : : : : : : @
| :::: : : : : : @ : : : # : : : : : : : : : @
| ::: : : : : : : @ : : : # : : : : : : : : : @
0 +----------------------------------------------------------------------->KB 0 29.48
Number of snapshots: 25
Detailed snapshots: [9, 14 (peak), 24]
日志的其余部分详细说明了内存分配的最高百分位数,您可以明确地看到哪种类型的类占用了堆内存的百分比(以及从调用堆栈的角度来看,分配来自何处),例如:
--------------------------------------------------------------------------------
n time(B) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
10 10,080 10,080 10,000 80 0
11 12,088 12,088 12,000 88 0
12 16,096 16,096 16,000 96 0
13 20,104 20,104 20,000 104 0
14 20,104 20,104 20,000 104 0
99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->49.74% (10,000B) 0x804841A: main (example.c:20)
|
->39.79% (8,000B) 0x80483C2: g (example.c:5)
| ->19.90% (4,000B) 0x80483E2: f (example.c:11)
| | ->19.90% (4,000B) 0x8048431: main (example.c:23)
| |
| ->19.90% (4,000B) 0x8048436: main (example.c:25)
|
->09.95% (2,000B) 0x80483DA: f (example.c:10)
->09.95% (2,000B) 0x8048431: main (example.c:23)
嗯,这不是那么容易做到的。首先m_word是一个可变大小的字符串,对吧?在std::string内部保存了一个字符数组。std::map也是如此。我猜你可以根据地图* TrieNode的大小得到一个粗略的估计,但这只是一个粗略的估计。
我认为使用外部工具进行代码分析会更有帮助。如果你没有任何工具,你甚至可以使用任务管理器:)。
您的"对象大小"是sizeof(std::string) + sizeof(bool) + m_word.capacity() +填充字节或sizeof(trieobject) + m_word.capacity()
这是我想出的一段GCC代码,您可以在测试程序中使用它,其中您只实例化类的一个对象并使用它进行一些典型的工作。代码替换了全局operator new()
和operator delete()
;因此,它将只通过::new
表达式和标准分配器跟踪分配,前提是标准分配器本身使用::operator new()
(这是GCC的情况)。
由于需要跟踪指针及其分配,因此需要单独的map,当然不能使用标准分配器本身;GCC的malloc-allocator来帮忙了。
我们使用一个静态初始化的全局变量使内存跟踪器在main
返回后打印它的数据。
#include <unordered_map>
#include <string>
#include <iostream>
#include <ext/malloc_allocator.h>
struct Memtrack
{
typedef std::unordered_map<void*, std::size_t, std::hash<void*>,
std::equal_to<void*>, __gnu_cxx::malloc_allocator<void*>> AllocMap;
static int memtrack;
static int memmax;
static AllocMap allocs;
Memtrack() { std::cout << "starting tracker: cur = " << memtrack << ", max = " << memmax << ".n"; }
~Memtrack() { std::cout << "ending tracker: cur = " << memtrack << ", max = " << memmax << ".n"; }
static void track_new(std::size_t n, void * p)
{
memtrack += n;
if (memmax < memtrack) memmax = memtrack;
allocs[p] = n;
std::cout << "... allocating " << n << " bytes...n";
}
static void track_delete(void * p)
{
const int n = int(allocs[p]);
memtrack -= n;
std::cout << "... freeing " << n << " bytes...n";
}
} m;
int Memtrack::memtrack = 0;
int Memtrack::memmax = 0;
Memtrack::AllocMap Memtrack::allocs;
void * operator new(std::size_t n) throw(std::bad_alloc)
{
void * const p = std::malloc(n);
Memtrack::track_new(n, p);
return p;
}
void operator delete(void * p) throw()
{
Memtrack::track_delete(p);
std::free(p);
}
int main()
{
std::cout << "Beginning of main.n";
std::unordered_map<std::string, int> m; // this piece of code
m["hello"] = 4; // is a typical test for working
m["world"] = 7; // with dynamic allocations
std::cout << "End of main.n";
}
典型输出:
starting tracker: cur = 0, max = 0.
Beginning of main.
... allocating 48 bytes...
... allocating 12 bytes...
... allocating 12 bytes...
End of main.
... freeing 12 bytes...
... freeing 12 bytes...
... freeing 48 bytes...
ending tracker: cur = 0, max = 72.
不重要。如果您有一些时间(如果您只对调试/优化目的的大小感兴趣,则可能是这种情况)。这种方法可能不适合生产代码!
#include <malloc.h>
template <typename T> int objSize(T const* obj) {
// instead of uordblks, you may be interested in 'arena', you decide!
int oldSize = mallinfo().uordblks;
T* dummy = new T(*obj);
int newSize = mallinfo().uordblks;
delete dummy;
return newSize - oldSize;
}
- 必须为 C++20 协程帧保留多少内存?
- 堆栈上的参考用途有多少内存
- 指针数组中将有多少内存分配
- 一个 Excel XLL 插件可以有多少内存?
- 在C 中存储对对象的引用需要多少内存
- 对象指针如何知道要删除多少内存
- 使用犰狳线性代数包存储矩阵需要多少内存
- std::vector-他将分配多少内存(在重新分配期间)
- 一个C++指针使用多少内存
- x64 进程可以在 4GB RAM 上占用多少内存
- 计算出一个程序(规划中)需要多少内存
- C/C++ 程序正在使用多少内存
- 哪些数据结构正在使用多少内存
- 表示一个地址需要多少内存
- 了解我有多少内存可用于一个动态向量c++
- 我怎么能看到我的程序消耗了多少内存
- 在x64中,我们可以通过malloc()获得多少内存
- 是否有一种方法可以测量特定函数从堆栈中消耗了多少内存?
- 在c++中,枚举数据类型消耗多少内存
- 对象消耗了多少内存