问题
TLDR; 我看到为我创建的每个透明代理对象不断泄漏ServerIdentity
个对象。
我正在生成AppDomains,作为沙盒某些第三方代码执行的机制,并利用MarshalByRefObject
和appDomain.CreateInstanceAndUnwrap()
生成透明代理来执行我的代码。但是,我编组的每个实例还创建了一个相应的ServerIdentity
,显然它由内部静态类保留。
我尝试过的事情
AppDomain
卸载AppDomain.Unload(appdomain)
会断开连接并清理AppDomain
实例,但是ServerIdentity
对象会保留并累积。RemotingServies.Disconnect(marshalbyrefobject)
会引发异常,因为它显然不会处理透明代理,因为它会引发以下错误:System.Runtime.Remoting.RemotingException: 'Cannot call disconnect on a proxy.'
我最想找到答案的是blog post,它描述了一个非常相似的问题。但是,我的代码中必须缺少其他上下文。
dotMemory屏幕截图
编辑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
保留的对象。实际上似乎是这种情况。对此问题有知识的人可以确认吗?