AppDomain代理生成的ServerIdentity对象的内存泄漏?

时间:2018-09-13 18:56:32

标签: c# .net memory-leaks .net-remoting

问题
TLDR; 我看到为我创建的每个透明代理对象不断泄漏ServerIdentity个对象。

我正在生成AppDomains,作为沙盒某些第三方代码执行的机制,并利用MarshalByRefObjectappDomain.CreateInstanceAndUnwrap()生成透明代理来执行我的代码。但是,我编组的每个实例还创建了一个相应的ServerIdentity,显然它由内部静态类保留。

我尝试过的事情

  1. 通过AppDomain卸载AppDomain.Unload(appdomain)会断开连接并清理AppDomain实例,但是ServerIdentity对象会保留并累积。
  2. 调用RemotingServies.Disconnect(marshalbyrefobject)会引发异常,因为它显然不会处理透明代理,因为它会引发以下错误:System.Runtime.Remoting.RemotingException: 'Cannot call disconnect on a proxy.'

我最想找到答案的是blog post,它描述了一个非常相似的问题。但是,我的代码中必须缺少其他上下文。

dotMemory屏幕截图

每个请求的新对象数量都会增加,不会收集垃圾 enter image description here

ServerIdentity实例密钥保留路径 enter image description here

编辑1
因此,我发现了导致2号项目符号中提到的异常的原因。基本上,您无法从主AppDomain调用RemotingServices.Disconnect(proxyInstance)。必须在辅助MarshalByRefObject中创建的真实AppDomain实例对象上完成此操作。基本上,我像这样创建了自己的MarshalByRefObject抽象实现。 我确认每个封送实例都在调用Disconnect()

public abstract class SandboxedInstance : MarshalByRefObject
{
    public sealed override object InitializeLifetimeService()
    {
        // This override implementation ensures the lifetime of this object until Dispose() is called.
        return null;
    }

    /// <summary>
    /// Method called internally when containing Sandbox is disposed, automatically disposing this object.
    /// </summary>
    internal void Disconnect()
    {
        RemotingServices.Disconnect(this);
    }
}

但是,这并没有解决我的问题。尽管已成功调用ServerIdentity,但RemotingServies.Disconnect(marshalbyrefobject)对象似乎仍然在徘徊。有谁知道发生了什么事吗?在这方面我几乎找不到文档。

编辑2
有谁可以证实这一理论?我读过一些文章,提到某些远程对象超出了Disconnect()的范围,但最终被清除了。基于此理论,我运行了dotMemory并观察了一段时间后是否清理了ServerIdentity对象,尤其是通过Lease保留的对象。实际上似乎是这种情况。对此问题有知识的人可以确认吗?

0 个答案:

没有答案