【问题标题】:How can I release DLL memory inside a Parallel.For?如何在 Parallel.For 中释放 DLL 内存?
【发布时间】:2014-07-10 07:31:36
【问题描述】:

在嵌套的Parallel.For 中,我动态加载/卸载不同的 DLL。 我注意到在“孩子”Parallel.For 的末尾没有释放内存。记忆似乎在“根”Parallel.For 之后被释放了。

Parallel.For(0, 100, j =>
{
     // Do stuffs 

     Parallel.For(0, maxIter, i =>
      {
          // Dynamically load DLL file
          NativeMethods.LoadLibrary(...)

          // Do stuffs with the DLL
          ... (call compute method)

         // Dynamically unload DLL file
         NativeMethods.FreeLibrary(...)
      });

     // Do stuffs 
}

// Do stuffs (DLL Memory seems to be release only here, not before)

我在许多不同名称的 DLL 中克隆了一个 DLL(复制文件并重命名)。 每个NativeMethods.LoadLibrary(...) 加载其中一个DLL。 DLL 是使用 /MD 选项编译的 C++ 非托管代码。 每个库只被Parallel.For中的一个线程使用

你能解释一下吗?

如何释放Parallel.For 中的DLL 内存?

【问题讨论】:

  • 你为什么首先在并行循环中加载和卸载库?
  • 最大限度地释放内存。我真的很想了解在这种情况下发生了什么。
  • 根据MSDN FreeLibrary 减少每个进程的引用计数。这意味着如果 refcount 大于 1,调用 FreeLibrary 可能不会卸载库。因此,澄清问题:您的 NativeMethods.LoadLibraryNativeMethods.FreeLibrary 是如何实现的?他们正在加载哪些库?那些在并行化中是独一无二的吗?同一个库是否有可能同时在两个或多个并行的上下文中?
  • 我在许多不同名称的 DLL 中克隆了一个 DLL(复制文件并重命名)。每个“NativeMethods.LoadLibrary(...)”都会加载其中一个 DLL。 DLL 是使用 /MD 选项编译的 c++ 非托管代码。每个库仅由 Parallel.For 中的一个线程使用
  • 是否可以读取'refcount'?

标签: c# memory dll unmanaged parallel.for


【解决方案1】:

我找到了解决办法。

事实上,我的原生 DLL 是动态与 msvcrt 运行时链接的(/MD 选项)。

每次我尝试执行FreeLibraryMSVCRTXXX.dll 仍然被加载,因为它依赖于其他加载的 DLL。 这就是为什么在 Parallel.For 之后释放所有非托管内存的原因

这篇文章对我帮助很大:Why does memory allocated from inside a DLL become invalid after FreeLibrary()?

我刚刚用 static 链接到 msvcrt 运行时重新编译了我的本机 DLL。

现在,在调用“FreeLibrary”后,内存已完全释放 :-)

【讨论】:

    猜你喜欢
    • 2013-10-08
    • 2021-05-20
    • 2015-08-10
    • 1970-01-01
    • 2010-12-06
    • 2011-12-08
    • 2012-01-18
    • 2011-11-03
    • 2023-04-05
    相关资源
    最近更新 更多