【问题标题】:How to dispose resources in third-party dll?如何在第三方dll中释放资源?
【发布时间】:2016-04-27 13:28:24
【问题描述】:

我有一个控制台应用程序需要创建多个 <T> 类型的对象,而 T 位于另一个我不拥有的 dll 中。

当一个T 类型的对象被创建时,它会在内存中加载一个XML,但它永远不会释放它。 因此,如果您创建了太多 T 类型的对象,则会引发 OutOfMemoryException。 dll 没有为该对象提供 dispose 方法,我无法直接与 XML 交互。

有没有办法处理由我不拥有的 dll 创建的某种类型的对象?

我正在使用 .NET 4.6

第三方dll是Trados Studio的dll,供了解程序的人使用。

【问题讨论】:

  • 你能把它加载到不同的appdomain中吗?听起来您需要向他们提交错误报告。
  • 事实上,dll 需要与我的应用程序位于同一文件夹中,否则我会从 dll 中获得 LicensingException。为什么将其加载到不同的 appdomain 可以解决问题?
  • 您可以卸载应用程序域。您无法卸载直接引用。
  • 将实例设置为 null 并创建一个新实例不允许垃圾收集器处理它吗?
  • @DanielA.White :它可以完美地将其加载到不同的应用程序域中!谢谢

标签: c# .net


【解决方案1】:

只需将第 3 部分对象的实例设置为 null 并创建一个新实例。垃圾收集器最终将清理您设置为 null 的对象,并且您不会再遇到内存不足异常。

public class Class1
{
    private StringBuilder sb = new StringBuilder();

    public void loadFile()
    {
        using(StreamReader sr = new StreamReader("C:\\test.txt"))   // Loads large text file. 
        {
            sb.Append(sr.ReadToEnd());
        }
    }
}

static void Main()
{
    fileloader.Class1 inst = new fileloader.Class1(); // Assume this is the instance of your 3rd party object. 

    do
    {
        if(inst == null)
        {
            inst = new fileloader.Class1();
        }

        for (int i = 0; i < 100; i++)
        {
            inst.loadFile();
        }

        inst = null;  // allows the object to be GC'ed. Without this i get the OutOfMemoryException

        Thread.Sleep(1000);

    } while (true);
}

【讨论】:

  • 我的不行,内存还在增加。
  • @Claudia 内存会增加,但垃圾收集器不会让它达到故障点。 GC 只会在它决定需要时运行。在我发布的示例程序中,使用中的内存在 300-600mb 之间反弹。你能尝试复制失败吗?失败需要多长时间?
  • 执行900次操作失败。
  • @Claudia 他们必须使用静态变量来存储信息。静态变量不会被 GC 处理。
  • @Claudia 有什么地方我可以得到这个 DLL,你能提供一些基本代码来重现这个问题吗?
【解决方案2】:

在运行时调用 GC.Collect() 可能会解决问题。 参考:https://docs.microsoft.com/en-us/dotnet/api/system.gc.collect?view=net-5.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 2015-03-29
    相关资源
    最近更新 更多