使用客户端激活的对象在app域中远程处理静态对象的生命周期

Cod*_*eld 6 .net c# remoting garbage-collection static-variables

我对AppDomain中的共享/静态对象生存期很好奇,其中RemotingCalls是创建共享对象的原因.

我们正在使用Remoting设置,它使用客户端激活的对象,我们只使用这些功能进入服务器.远程对象设置为单例.

服务器设置通道并使用RemotingConfiguration.Configure加载配置文件.

其中一些服务器功能触摸并使用服务器上的一些静态(在vb.net中共享)变量.我无法找出这些静态变量的生命周期,它们是在第一次触摸时创建的(静态构造函数运行).使用日志记录我无法看到对象dispose/finalize发生.

连接到远程服务器后等待几分钟,看到共享对象活得很好.

问题:

那么这个远程处理设置中静态对象的预期实时时间是多少.它们是否与AppDomain一样长,或者当Remoting对象被交换时它们会被循环使用.如果需要,延长寿命的正确方法是什么?

答案:

静态类型存在于AppDomain中,因为它们是第一次访问,直到AppDomain被卸载.因此,只要AppDomain正在运行,您就不需要延长其生命周期.

Vla*_*rov 5

在租约到期之前,远程处理对象不会被垃圾收集 - 租约会保护它们不受GC影响,因为没有明显的可见参考.默认的租期为5分钟,垃圾收集器可能会在几分钟内运行(取决于负载,内存使用情况等),然后对您的对象的最后一次引用应该消失.只有在发生这一切之后,才应在下一次 GC运行时收集实例对象.静态对象,但是,不会被垃圾收集所有.

至于问题的第二部分,延长生命周期的正确方法称为"赞助" - 基本上当租约到期时,服务器会询问客户是否有人愿意继续使用此对象.有关于这个问题的详细漂亮的文章在这里.不要只将寿命设置为无穷大.


Ale*_*Aza 3

静态字段永远不会被垃圾回收。看看Jeffrey Richter 的文章
静态字段被垃圾收集器视为根,因此垃圾收集器将始终假定使用静态字段。

静态字段在加载所有者类型时初始化。JIT 编译器在需要构建方法并看到对此类型的引用时加载类型。加载后,该类型在整个 AppDomain 生命周期内都会保留在那里,因此属于该类型的字段(静态字段)引用的任何内容都将被视为已使用的引用,并且不会被垃圾收集。

另外,关于此声明:

我无法找出这些静态变量的生命周期是多少,它们在第一次被触摸时被创建(静态构造函数运行)。

从技术上讲,静态变量不一定在静态构造函数中第一次被“触及”。考虑这样的类:

public static class Test
{
    private static MyType myType;

    static Test()
    {
        myType = new MyType();
    }
}
Run Code Online (Sandbox Code Playgroud)

静态构造函数(类型构造函数)永远不会被调用,除非您有正在执行并引用此类型的代码,例如var x = Test.myType;. 嗯,这可能取决于“触摸”的确切含义。

答案:

静态类型从第一次访问开始一直存在于 AppDomain 中,直到 AppDomain 被卸载。因此,只要 AppDomain 正在运行,您就不需要延长它们的生命周期。