我正在尝试使用诊断工具和内存使用情况快照在C#应用程序(使用c ++ / cli和c ++)中调试奇怪的内存泄漏。但是我发现了一个奇怪的问题。
当我在VS2017中运行Heap Profiling的情况下运行调试时,内存消耗恒定且程序按预期运行。关闭堆分析后,程序将泄漏内存,线性增加。完成的工作是相同的,我已经在控制台上打印了工作进度,并且我确定两个程序都完成了相同的工作,但是一个程序使用了恒定的内存,另一个程序使用了线性增加的内存(当同一工作完成时使用了2倍内存)。从外观上看,当使用堆分析触发GC时,会释放一些内存,而当不使用堆分析时,不会释放任何内存。
有人知道堆分析如何影响这一点吗?本机内存泄漏。
[EDIT1]来自Performance Profiler的数据->内存使用情况
Object Type Reference Count Module
shared_ptr_cli<GeoAtomAttributes> TestBackEnd64.dll
shared_ptr_cli<GeoAtomAttributes> [Finalization Handle] 856,275 TestBackEnd64.dll
shared_ptr_cli<GeoAtomAttributes> [Local Variable] 1 TestBackEnd64.dll
GeoAtomAttributesCli [Local Variable] 1 TestBackEnd64.dll
答案 0 :(得分:1)
可以用gc释放的内存不应被视为泄漏的内存,而应被视为符合垃圾回收条件的内存。由于下次执行gc时,将收集此内存并将其用于新的对象分配。
其他想法;
Gc在托管堆上运行,本机库在本机堆上分配内存。因此,它不会影响本机库的内存管理。但是您应该注意以下情况。(虽然可能不是您的情况)
如果您将pinned数据结构传递给本机代码,并在free方法(包装类的)上将这些句柄传递给Object.Finalize;在这种情况下,只能在包装器类排队进行终结处理时收集固定的内存。在托管类的终结处理方法中调用本机代码的清除函数(*)也会导致类似的情况。我认为这些是不良做法,不应使用,而应尽快进行这些清理。
(*)即使在托管堆中不需要gc的情况下,这种情况也可能导致您的总进程内存消耗膨胀。