代码之家  ›  专栏  ›  技术社区  ›  Steve Sheldon

GC.添加内存压力

  •  6
  • Steve Sheldon  · 技术社区  · 15 年前

    我正在用C语言编写一个应用程序,它使用第三方COM DLL,这个DLL在非托管内存中创建了大量资源(如位图、视频、数据结构)。在四处挖掘的时候,我遇到了一个叫垃圾收集者的电话:

    GC.AddMemoryPressure(long long bytesAllocated)
    

    在MSDN中记录如下:

    http://msdn.microsoft.com/en-us/library/system.gc.addmemorypressure.aspx

    我想我有两个问题。。。

    1. 当dll是第三方时,我如何知道要添加多少内存压力,并且我不可能确切地知道这个dll分配了多少内存。
    4 回复  |  直到 15 年前
        1
  •  5
  •   Daniel Earwicker    15 年前

    在任何本机/托管混合进程中,都存在本机/托管内存使用的混合情况。如果两者之间没有GC控制的关系,那么就不需要这个API。例如,如果托管代码中存在某些确定性状态更改,导致分配和释放本机内存,那么GC所能做的任何事情都不会强制释放本机内存。

    但是,通常有本机内存由具有终结器的托管对象持有。所以GC 可以 减少本机堆的大小,只需触发一个集合并运行那些终结器。

    至于你应该说多少,这可能不是你可以通过纯粹的分析,特别是与第三方图书馆编造一个答案。您需要运行性能监视器,运行分配大量第三方对象的测试,并查看本机字节和CLR内存计数器以了解它们之间的关系。

    Marshal.ReleaseComObject . 请注意,您需要使用goofy循环使其摆脱对象:

    while (Marshal.ReleaseComObject(obj) != 0) 
    {
    }
    
        2
  •  3
  •   plinth    15 年前

    假设我有这样一个物体:

    public class SomeImageType : IDisposable
    {
        public int Width { get; private set; }
        public int Height { get; private set; }
        public PixelFormat PixelFormat { get; private set; }
        IntPtr ImageData { get; private set; }
        // implementation of constructor and IDisposable not shown
    }
    

    这需要多少内存?20字节+对象开销?到了收集的时候,如果这个对象没有引用,就没有任何区别。但是需要20个字节吗?他妈的不-这是个图像。所以取20乘以宽度,高度和每像素字节数,你就得到了占用(可能)兆字节的东西。告诉GC增加内存压力,就是说有冰山在吞噬资源。当您处理对象时,您当然会释放内存并告诉GC释放压力。这两个调用让您向GC提示在圆K处有一些奇怪的事情正在进行中,也许它希望以不同的方式安排收集。

        3
  •  2
  •   Cylon Cat    15 年前

    非托管资源的问题是,包装或使用它们的.NET类需要有终结器,并实现IDisposable()模式。如果调用Dispose(),它应该立即处理非托管资源,并且还应该抑制终结器。如果不调用Dispose(),则会出现真正的内存问题,向垃圾收集器添加“压力”并不能解决问题。

    所以调用Dispose()。一定不要错过。

        4
  •  1
  •   SLaks    15 年前

    这样做对你来说并不重要,除非你注意到你认为是由GC引起的记忆问题。