我正在用C#编写一个使用第三方COM DLL的应用程序,这个DLL在非托管内存中创建了大量资源(如位图,视频,数据结构).在挖掘时,我遇到了垃圾收集器的以下调用:
GC.AddMemoryPressure(long long bytesAllocated)
它在MSDN中记录在这里:
http://msdn.microsoft.com/en-us/library/system.gc.addmemorypressure.aspx
这听起来像我应该调用的东西,因为这个外部dll正在创建CLR不知道的大量资源.
我想我有两个问题……
>我怎么知道当dll是第三方时要添加多少内存压力,而且我不可能确切地知道这个dll分配了多少内存.
>这样做有多重要?
解决方法
在任何混合的本机/托管进程中,存在本机/托管内存使用的混合.如果两者之间没有GC控制的关系,那么就不需要这个API.例如,如果托管代码中存在某些确定性状态更改导致本机内存被分配和释放,那么GC无法执行任何操作就会强制释放本机内存.
但是,通常由具有终结器的托管对象保留本机内存.因此,GC可以通过触发集合并使这些终结器运行来减小本机堆的大小.
因此,如果您有很多这样的事情,可能需要调用此API(就像文档所说).
至于你应该告诉它多少,你可能不会通过纯粹的分析来解决问题,特别是对于第三方库.您需要运行性能监视器,运行分配大量第三方对象的测试,并查看本机字节和CLR内存计数器以查看它们之间的关系.
当您使用COM对象时,实际上可以通过使用Marshal.ReleaseComObject确定性地强制实例在您知道不再需要它们时进行清理.请注意,您需要使用一个愚蠢的循环来使其摆脱对象:
while (Marshal.ReleaseComObject(obj) != 0) { }