我正在创建一个小型缓存守护进程,我希望将其内存使用量限制在大约指定的数量。然而,似乎有一个问题,只是试图计算多少内存正在使用。
每次创建CacheEntry对象时,它都会将一个CacheEntry对象的大小(显然是64个字节)加上内部数组中使用的字节数添加到计数器中,用于计算正在使用的字节数。当删除CacheEntry对象时,它会减去该数量。我可以确定,至少数学是正确的。
然而,当在NetBeans中运行时,内存分析器报告的数字却大不相同。确切地说,大约高出两倍。这不是内存泄漏,它与当前存在的CacheEntry对象的数量特别相关。增加存储在内部数组中的数据量实际上使数据更接近于一起(如果计算不当,则与之相反);由此,我得出结论,内存中有一个CacheEntry对象的开销几乎是sizeof of ()所报告的开销的两倍。它不会以步子或“块”的形式上升。
有什么共同的原因可能发生这种情况吗?
更新:只是检查一下,我在没有配置文件的情况下运行了测试。Linux以任何一种方式报告相同的VmHWM/VmRSS,因此内存分析器绝对不会影响计算。
发布于 2012-02-21 05:04:58
这种内存膨胀是由于使用new造成的,特别是在相对较小的对象上。在Windows上,动态分配的内存每次都会产生16字节或24字节的开销;我还没有找到Linux的确切数字,但大致相同。这是因为每个分配的块都需要记录其位置和大小(可能不止一次),以便以后能够准确地释放它。
据我所知,正在运行的程序也不确切地知道其中涉及到多少开销,至少在程序员可以访问的任何方面都是如此。
一般来说,大量的小对象应该使用一个内存池,这既可以提高速度,也可以节省内存。
发布于 2012-02-13 17:00:45
也许分析器正在添加引用对象来跟踪对象?在release中运行应用程序时,会看到相同的结果吗?
发布于 2012-02-13 17:01:18
,有什么共同的原因可能会发生这种情况吗?
是的,这可能是内存管理器的内部碎片和开销。如果您的数据类型很小(例如。sizeof(CacheEntry)是8字节),使用这种数据类型的new可能会产生更大的内存块。它部分用于malloc的内部簿记(它通常将块的大小存储在某个地方),部分用于在其自然边界上对齐数据类型所需的填充(例如。8字节数据+4字节簿记+4字节填充需要在8字节边界上对齐整件事情)。
您可以通过从一个连续的CacheEntry数组(例如。CacheEntry array[1000]精确地取1000*sizeof(CacheEntry)字节)。您必须跟踪数组中各个元素的使用情况,但在不需要额外内存的情况下,这应该是可行的。(例如,通过在空闲条目的位置运行一个自由条目列表)。
https://stackoverflow.com/questions/9264456
复制相似问题