如何查找任何对象使用的内存
class Help
{
public:
Help();
~Help();
typedef std::set<string> Terms;
typedef std::map<string, std::pair<int,Terms> > TermMap;
typedef std::multimap<int, string, greater<int> > TermsMap;
private:
TermMap terms;
TermsMap termsMap;
};
如何通过对象term
和termsMap
找到使用(以字节为单位)的内存。我们有图书馆吗?如何查找任何对象使用的内存
的sizeof()
运营商应该做的是:
size_t bytes = sizeof(Help::TermMap);
如果你正在寻找的实际内存块的指针,它的数值应该是它。 (然后只需添加字节数,并且您有块的结尾)。
如果您正在寻找一个对象的全部内存使用情况,这通常无法在C++中解决 - 虽然我们可以通过sizeof()
获取实例本身的大小,但该对象始终可以根据需要动态分配内存。
如果你能找出一个容器中的各个元素有多大,你可以得到一个下界:
size = sizeof(map<type>) + sum_of_element_sizes;
但请记住,该容器仍然可以分配更多的内存作为实现细节,对于像vector
和string
这样的容器,您必须检查allocated size。
考虑到这是一个粗略的低估。在许多情况下,像地图一样,STL必须包含其他东西(地图是平衡树,所以它至少需要三个指针(左边,右边,父 - 父来保证快速迭代器横向)以及一些保持信息的方式平衡不变,可能是一个额外的值(整数,彩色字节)...和元素大小必须同时考虑密钥和值。 – 2010-01-29 08:19:57
David,将其更改为*下限*以使其更清晰,其余应该是覆盖*实现细节*。 – 2010-01-29 09:09:21
简短的回答:没有
龙答:
- >基本对象是。 sizeof(<类型>)但这只对有限的事情有用。
- >容器及其包含的成员:NO
如果您对用于实现这些目标的结构假设你可以估计它。但即使这样也不是很有用(除了矢量的特定情况外)。
STL的设计者故意没有定义这些容器应该使用的数据结构。这有几个原因,但其中一个原因(在我看来)是阻止人们对内部进行假设,从而尝试去做那些没有被界面封装的愚蠢的东西。
所以这个问题归结为为什么你需要知道尺寸?
你真的需要知道大小(不太可能,但可能)。
或者有没有一项任务是您试图实现的,您认为您需要的尺寸?
我们如何才能找到对象长期和 termsMap使用的内存(在 字节)。我们有图书馆吗?
您应该使用您自己的分配器类型。
typedef std::set<string,
your_allocator_1_that_can_count_memory_consumption_t> Terms;
typedef std::map<string, std::pair<int,Terms>,
your_allocator_2_that_can_count_memory_consumption_t> TermMap;
typedef std::multimap<int, string, greater<int>,
your_allocator_3_that_can_count_memory_consumption_t> TermsMap;
我还没有检查这个想法的std :: string,所以如果它是很难实现只使用自己的类fixed_string这只是包装个char [MAX-串lenght。
而当你需要在你的程序中找出内存消耗时,只需从your_allocator_1_that_can_counts_memory_consumption_t
,your_allocator_2_that_can_counts_memory_consumption_t
, your_allocator_3_that_can_counts_memory_consumption_t
得到它。
编辑
对于UncleBens我想澄清我的观点。
就我所了解的ARV问题而言,有必要知道为set :: set和std :: map分配了多少内存,包括为该集合和地图的元素分配的所有内存。所以它不只是sizeof(术语)。
所以我只是建议一个非常简单的分配器。没有进入太多细节,可能是这样的:
template <class T>
class your_allocator_1_that_can_counts_memory_consumption_t {
public:
// interfaces that are required by the standart
private:
std::allocator<T> std_allocator_;
// here you need to put your variable to count bytes
size_t globale_variable_for_allocator_1_to_count_bytes_;
};
这个分配器只计算分配和释放的字节数和真正的分配和释放使用它的成员std_allocator_。我可能需要在gdb下调试它,以便在malloc()和free()上设置一个断点,以确保每次分配和释放实际都通过我的分配器。
如果您将此意见指向某些问题,我将不胜感激,因为我已经在我的Windows,Linux和HP-UX上运行的程序中实现了它,并且我只是简单地询问我的分配器以查找多少内存我的每个容器都使用。
我怀疑,除非你的分配器使用了一些非常特定于操作系统的分配例程,否则你甚至无法告诉内存使用情况如果我没有弄错,如果你的代码包含高级别为'malloc(n);'它可能仍然是完全实现定义实际得到多少内存“用完”。 – UncleBens 2010-01-29 20:28:57
查看已编辑的部分。 – 2010-01-30 10:46:04
关于'它可能仍然完全实现ation定义了多少内存实际上被“用完”了。那是真实的。例如,在HP-UX上,当您询问5个字节时,实际上已经分配了16个字节,因为libc关心内存碎片。 但是,我还从HP-UX/Linux获得有关分配给进程的内存量的信息。结果我知道真正的内存消耗更大。 顺便说一句,ARV没有说他想知道容器的确切内存消耗,包括libc可能会添加什么内容。 – 2010-01-30 11:09:16
'sizeof'是一个运算符,而不是一个函数。 – 2010-01-29 06:39:51
@Carl Norum:你是对的。谢谢你的提醒! – 2010-01-29 06:41:19
嗯。这看起来没有用,原因有两个:成员是私有的,并且不允许你使用非静态成员变量的大小。有趣! – 2010-01-29 06:43:18