【问题标题】:Clean up of memory leak in unmanaged code清理非托管代码中的内存泄漏
【发布时间】:2023-03-05 08:10:01
【问题描述】:

我一直在徘徊 3rd 沙盒内存泄漏的最佳方法 从 .Net 框架中使用方库时。

我有一个用 C++/cli 编写的第三方库,它会泄漏大量内存。

有没有人发现了一种优雅的清理方法 使用 .Net 的非托管内存泄漏?

最好的问候,

【问题讨论】:

  • 最好的方法是向库的供应商提供错误报告,并让他们修复它。或者你只是使用了错误的 API?也许您忘记在 API 中调用“释放”或“关闭”函数?
  • 即使从非托管代码中,您将如何清理它?如果您有内存泄漏并且没有指向内存的指针,那么您无法释放/删除它。
  • 修复库?说真的,您不应该依赖损坏的库。即使您可以“清理”内存,库也可能会调用未定义的行为。
  • c++ dll代码是我写的,但是有点大所以不能添加
  • 你怎么知道内存泄漏是库的责任?听起来您已经习惯了托管内存 :) 您必须研究 API 以确定哪些内存是您的责任,哪些由库保留。

标签: c# memory-leaks c++-cli


【解决方案1】:

不可能,除非您当然可以修改和修复 C++ 代码,但可能这不是一个选项。我过去也遇到过同样的问题,解决方案是将泄漏代码托管在一个进程中(注意:应用程序域 not 足够)并定期关闭该进程。使用一些 IPC 技术与该流程实例进行通信。即使您需要关闭一个进程,您也可以选择创建一个包含两个该进程的池以响应响应,因此您可以轻松切换到另一个已经运行的实例。

【讨论】:

    【解决方案2】:

    您可以运行您选择的内存检查器来查找泄漏。这是一个非常简单的过程。我使用英特尔 Inspector(英特尔并行工作室的一部分),但其他人会做到这一点。

    为了沙盒分配,您可以使用 malloc 替换,例如 google_malloc 并修改它以具有 free_all_memory 函数(如果它还没有)。

    这不是很优雅,但如果您的非托管代码状态非常糟糕,这是一个选择。

    【讨论】:

      【解决方案3】:

      非托管对象: 非托管对象是在 .NET 库的控制之外创建的,并且不受 CLR 管理。此类非托管代码的示例是 COM 对象、文件流、连接对象、互操作对象。 (基本上是 .NET 代码中引用的第三方库。)。 GC 无法自行处理非托管对象,因为它对此一无所知。因此,例如,假设您在 C++/CLI 库类中使用了一个指针,然后在该类的析构函数 (~) 中删除了该指针。这会导致内存泄漏because, In C++/CLI, the notation ~ is already reserved for deterministic destructors (because all destructors are deterministic in C++). So, here we must use the notation ! instead

      IDisposable、Finalizer 和 GC.SuppressFinalize() 的 C++/CLI 示例

      ref class ClassName {
      public:
        ClassName() : m_isDisposed(false) {
          m_unmanagedData = new CustomObject();
        }
      
        ~ClassName() {
          if (m_isDisposed)
             return;
      
          this->!ClassName();
          m_isDisposed = true;
        }
      
        // Finalizer
        !ClassName() {
          delete m_unmanagedData;
        }
      
      private:
        bool m_isDisposed;
        CustomObject * m_unmanagedData;
      };
      

      按照 Microsoft 的此文档指南找出 C++/CLI 库中的内存泄漏 Find memory leaks with the CRT library

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-30
        • 2020-07-11
        • 2010-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-03
        • 1970-01-01
        相关资源
        最近更新 更多