Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 传递到已卸载AppDomain的服务内存泄漏_C#_.net_Memory Leaks_Appdomain - Fatal编程技术网

C# 传递到已卸载AppDomain的服务内存泄漏

C# 传递到已卸载AppDomain的服务内存泄漏,c#,.net,memory-leaks,appdomain,C#,.net,Memory Leaks,Appdomain,我在AppDomains的上下文中遇到内存泄漏。我将其精简为以下内容: 我得到了3个项目,两个库项目和一个控制台项目:共享,dynamicallyadable和RemotingTimeoutPrototype(控制台程序)。共享包含dynamicallyadable和RemotingTimeoutPrototype使用的接口。两个引用在编译时共享。在任何项目之间都没有其他编译时引用 共享包含以下内容: public interface IHostService { string GetS

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

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

共享包含以下内容:

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();
    }
}
console项目包含
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";
    }
}
现在,当我让它运行一段时间后,内存消耗不断增加,最终我遇到了OutOfMemoryException

我希望,如果卸载了持有代理的域,那么代理也会被卸载,并且不再有对具体Alpha的引用,因此这将被收集。但显然不是这样

注意,我还通过引用mscoree并使用以下代码枚举加载的域,检查了域是否确实正在卸载:

var runtimeHost = new CorRuntimeHost();
runtimeHost.EnumDomains(out handle);
// etc.
另外,如果我将一个处理程序附加到otherDomain.DomainUnload(),则该处理程序的调用很好


有人能解释一下吗?

这可能是一个典型的阻塞终结线程问题(正如您在while中循环,可能是STA线程,并且从不显式地将控制权交给其他线程)。即使卸载/处置域,它也可能位于内存中,因为它尚未完成。阅读更多内容:-特别是“阻止终结线程”部分(我是作者)

我刚刚阅读了你的文章。明天我将按照您的描述使用WinDbg(现在我住的地方已经快凌晨2点了;)来检查是否在“准备完成”对象中看到任何构建。不过,我不知道我的情况会怎样。可能相关:while循环是我的Main所包含的,没有其他内容了。我只是尝试了一种更简单的方法来检查代理的RemoteClass实例是否正在被销毁,方法是向RemoteClass添加一个析构函数,如下所示:~RemoteClass(){Console.WriteLine(“正在销毁”);}-我看到控制台消息,因此代理实例正在被销毁。这将击败终结器理论,不是吗?我猜在这个线程中应该销毁/终结的不是RemoteClass,而是代理。无论如何,您是否尝试在GC.Collect之后添加WaitForPendingFinalizers?
var runtimeHost = new CorRuntimeHost();
runtimeHost.EnumDomains(out handle);
// etc.