我在AppDomains
的上下文中遇到内存泄漏。我已将其剥离到以下内容:
我有3个项目,两个库项目和一个控制台项目:Shared,DynamicallyLoadable
和RemotingTimeoutPrototype
(控制台程序)。共享包含DynamicallyLoadable
和RemotingTimeoutPrototype
使用的接口。两者都在编译时引用Shared。任何项目之间都没有其他编译时引用。
共享包含:
public interface IHostService
{
string GetStuff();
}
public interface IRemoteClass
{
IHostService Alpha { get; set; }
string CallHostServices();
}
DynamicallyLoaded只包含一种类型:
public class RemoteClass : MarshalByRefObject, IRemoteClass
{
public IHostService Alpha { get; set; }
public string CallHostServices()
{
Console.WriteLine("Domain {0}, RemoteClass.CallHostServices():", AppDomain.CurrentDomain.Id);
return Alpha.GetStuff();
}
}
控制台项目包含IHostService
:
public class Alpha : MarshalByRefObject, IHostService
{
readonly byte[] mBuffer = new byte[100*1024*1024];
public Alpha()
{
for (var i = 0; i < mBuffer.Length; ++i)
mBuffer[i] = (byte) (i%256);
}
public string GetStuff()
{
return "Alpha";
}
}
Program.Main包括:
while (true)
{
var otherDomain = AppDomain.CreateDomain("OtherDomain");
var proxy =
(IRemoteClass)
otherDomain.CreateInstanceFromAndUnwrap("../../../DynamicallyLoadable/bin/debug/DynamicallyLoadable.dll",
"DynamicallyLoadable.RemoteClass");
var alpha = new Alpha();
proxy.Alpha = alpha;
Console.WriteLine(proxy.CallHostServices());
Thread.Sleep(TimeSpan.FromSeconds(2));
AppDomain.Unload(otherDomain);
RemotingServices.Disconnect(alpha); // this was just an attempt, doesn't change a thing whether it's there or not
GC.Collect(); // same here, this shouldn't really be necessary, I just tried it out of despair
}
现在,当我让它运行一段时间后,内存消耗不断增加,最终我遇到了OutOfMemoryException。
我希望如果卸载代理的域名,那么代理也会被卸载,并且不再引用具体的Alpha,所以这将被收集。但显然不是。
请注意,我还通过引用mscoree并使用以下代码的代码枚举加载的域来检查域是否真正被卸载:
var runtimeHost = new CorRuntimeHost();
runtimeHost.EnumDomains(out handle);
// etc.
另外,如果我将处理程序附加到otherDomain.DomainUnload(),则可以正常调用此处理程序。
有人可以对此有所了解吗?
答案 0 :(得分:0)
这可能是阻塞终结线程的典型问题(因为你有while循环,可能是STA线程,并且永远不会明确地控制另一个线程)。即使您卸载/处置域,它也可能在内存中,因为它尚未最终确定。在这里阅读更多内容:http://alexatnet.com/articles/memory-leaks-in-net-applications - 特别是“Blocked Finalization Thread”部分(我是作者)