代码之家  ›  专栏  ›  技术社区  ›  Ohad Schneider

在应用程序出口上释放GCHANDLE

  •  2
  • Ohad Schneider  · 技术社区  · 14 年前

    说我有

    var hGCFile = GCHandle.Alloc(buffer, GCHandleType.Pinned)
    

    调用一些非托管函数

    SaveStream(hGCFile.AddrOfPinnedObject())
    

    此外,假设上面的函数保存缓冲区地址并在应用程序的整个生命周期中使用它。

    在这种情况下,打电话有什么好处吗

    hGCFile.Free()
    

    在关闭我的应用程序之前?只是我猜CLR会在appdomain被拆除后再这么做

    3 回复  |  直到 14 年前
        1
  •  3
  •   Hans Passant    14 年前

    好吧,定稿人 缓冲器 永远不会跑。很难看出这有什么关系,如果它是一个里面有任何有趣的东西的物体,你就无法把它钉住。

    它是 非常 对垃圾收集器不友好的是,它必须不断地绕过障碍,并且不能很好地压缩堆,从而使您的应用程序能够最好地使用CPU缓存。尤其糟糕的是,如果它是在0代,它将是。

    很少有好的理由让GC这么困难,只需分配 真实的 无法移动的记忆。使用Marshal.alloctaskmem()和Marshal.StructureToPtr()(如果需要)。现在你 卸载AppDomain时释放内存并不会终止进程。那个人会死的。

    但请注意,AppDomain的生命周期是 以任何方式与非托管代码的生存期关联。加载的DLL不会与AppDomain一起卸载。从您的问题中不清楚这个非托管代码是否仍然可以使用该缓冲区,因为它仍然存在。如果是,那就是 真正地 重要的是不要使用固定记忆。

        2
  •  2
  •   Pieter van Ginkel    14 年前

    AppDomain 卸载后,可以保证 应用程序域 被释放。

    前几天读到他们实际上在 应用程序域 已创建,卸载后:)。

        3
  •  0
  •   Aliostad    14 年前

    一旦你的应用退出,你需要确保所有 非受管的 资源被释放。 GCHandle 处理 管理 资源(CLR堆),因此不需要执行任何操作。

    不松开别针 G手柄 将导致GC无法移动对象并压缩堆中使用的内存。因此,这将是所有管理内存,如果应用程序退出,这已经不再重要了。