gpt4 book ai didi

c# - 传递给卸载的 AppDomain 的服务的内存泄漏

转载 作者:行者123 更新时间:2023-11-30 18:28:49 24 4
gpt4 key购买 nike

我在 AppDomains 上下文中遇到内存泄漏。我已将其简化为以下内容:

我有 3 个项目,两个库项目和一个控制台项目:Shared、DynamicallyLoadableRemotingTimeoutPrototype(控制台程序)。 Shared 包含 DynamicallyLoadableRemotingTimeoutPrototype 使用的接口(interface)。两者都在编译时引用共享。任何项目之间都没有其他编译时引用。

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(),则可以正常调用该处理程序。

任何人都可以阐明这一点吗?

最佳答案

这可能是终止线程阻塞的典型问题(因为您可能在 STA 线程中有 while 循环,并且从不显式地将控制权交给其他线程)。即使您卸载/处置域,它也可能在内存中,因为它没有最终确定。在这里阅读更多:http://alexatnet.com/articles/memory-leaks-in-net-applications - 特别是“Blocked Finalization Thread”部分(我是作者)

关于c# - 传递给卸载的 AppDomain 的服务的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24222622/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com