我有一个图形程序,我一遍又一遍地创建和销毁相同的对象。总而言之,有140个对象。它们被删除和新建,使得数字永远不会增加140.这是一个要求,因为它是一个压力测试,即我不能有内存池或虚拟对象。现在我相当确定没有任何内存泄漏。我也在使用内存泄漏检测器,它没有报告任何泄漏。
问题是程序的内存占用量不断增加(尽管速度很慢,比对象被销毁/创建的速度慢)。那么我的问题是,增加内存占用是否是内存泄漏的可靠信号,还是有时会欺骗?
编辑:我使用new / delete来创建/销毁对象
答案 0 :(得分:3)
这种行为似乎可能来自没有泄漏的情况。
您的堆是否有可能获得fragmented?
假设您进行了大量n
的分配。你释放所有这些,这使你的C库将这些缓冲区插入一个空闲列表。然后,其他一些代码路径会使分配小于n
,因此空闲列表中的这些块会被分成更小的单元。然后循环的下一次迭代执行另一批大小为n
的分配,并且空闲列表不再包含该大小的连续内存,并且malloc
必须向内核请求更多内存。最终那些“小于 - n
”分配被释放,就像你的“n
大小”分配一样,但是如果你运行足够的迭代来存在碎片,我可以看到这个过程逐渐增加它的记忆足迹。
避免这种情况的一种方法可能是分配所有对象一次,而不是继续分配/释放它们。由于您使用的是C ++,因此可能需要使用placement new或类似内容。由于您使用的是Windows,我可能还会提到Win32在一个进程中支持having multiple heaps,所以如果您的对象来自与其他分配不同的堆,您可以避免这种情况。
答案 1 :(得分:2)
这取决于你是在CLR(或带有垃圾收集器的虚拟机)下还是仍处于旧模式(如C ++,MFC等......)
当你有一个GC时 - 你无法确定,只有你测试它足够长。 GC现在可以决定不清理你的对象......(有办法强迫它)
在本机应用程序中,是的,足迹增加可能意味着泄漏。
有一些用于c ++的工具(非常好的工具)可以找到这些泄漏(google devpartner或boundschecker)
我想有一些c#和Java工具。
答案 2 :(得分:2)
如果您的应用程序的进程占用空间增加超出了合理的限制,这取决于您的应用程序及其功能,并且继续增加,直到最终您(将)用完虚拟内存,您肯定会有内存泄漏。
答案 3 :(得分:1)
尝试CRT中包含的内存分配测试:http://msdn.microsoft.com/en-us/library/e5ewb1h3%28VS.80%29.aspx
他们帮了很多。
但是我注意到,如果你看一些因素,应用确实会改变他们的内存消耗。 Windows 7还可能在内存分配中创建额外的填充以修复错误:http://msdn.microsoft.com/en-us/library/dd744764%28VS.85%29.aspx
答案 4 :(得分:0)