1

我正在尝试使用诊断工具和内存使用快照来调试 C# 应用程序(使用 c++/cli 和 c++)中奇怪的内存泄漏。但我发现了一个奇怪的问题。

当我在 VS2017 中运行调试并启用堆分析时,内存消耗是恒定的,并且程序按预期运行。当 Heap Profiling 关闭时,程序会泄漏线性增加的内存。完成的工作是相同的,我在控制台中打印了工作进度,我确信这两个程序都完成了相同的工作,但是一个使用恒定内存,另一个使用线性增加的内存(当相同的工作完成时使用 2 倍内存)。从视觉上看,当使用 Heap Profiling 触发 GC 时,会释放一些内存,而在不使用 Heap Profiling 时不会释放内存。

有谁知道堆分析如何影响这一点?本机内存泄漏。

[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
4

1 回答 1

1

可以通过 gc 释放的内存不应被视为泄漏内存,而应被视为符合垃圾回收条件的内存。因为下次执行 gc 时,该内存将被收集并用于新的对象分配。

其他想法;

Gc 在托管堆上运行,本机库在本机堆上分配内存。所以它不会影响原生库的内存管理。但是您应该注意以下情况。(但这可能不是您的情况)

如果您将固定数据结构传递给本机代码并在您的Object.Finalize方法(包装类)上释放这些句柄;在这种情况下,只有在包装类排队等待终结时才能收集固定内存。在托管类的终结方法中调用本机代码的清理函数(*)也会导致类似的情况。我认为这些都是不好的做法,不应该使用,而是应该尽快完成这些清理工作。

(*) 这种情况可能会导致您的总进程内存消耗膨胀,即使托管堆中不需要 gc。

于 2018-12-11T17:28:39.667 回答