我对AppDomain中的共享/静态对象生存期很好奇,其中RemotingCalls是创建共享对象的原因。
我们正在使用Remoting设置,它使用客户端激活的对象,我们只使用这些功能进入服务器。远程对象设置为单例。
服务器设置一个频道,并使用RemotingConfiguration.Configure加载配置文件。
其中一些服务器功能触摸并使用服务器上的一些静态(在vb.net中共享)变量。我无法找出这些静态变量的生命周期,它们是在第一次触摸时创建的(静态构造函数运行)。使用日志记录我无法看到对象dispose / finalize发生。
连接到远程服务器后等待几分钟,看到共享对象活得很好。
问题:
那么远程设置中静态对象的预期实时时间是多少。它们是否与AppDomain一样长,或者当Remoting对象被交换时它们会被循环使用。如果需要,延长寿命的正确方法是什么?
答案:
静态类型存在于AppDomain中,因为它们是第一次访问,直到卸载AppDomain。因此,只要AppDomain正在运行,您就不需要延长其生命周期。
答案 0 :(得分:5)
Remoting对象在租约到期之前不会被垃圾收集 - 租约会保护它们免受GC的攻击,因为它们没有明显的可见参考。默认的租期为5分钟,垃圾收集器可能会在几分钟内运行(取决于负载,内存使用情况等),然后对您的对象的最后一次引用应该消失。只有在发生这一切之后,才应在 next GC运行中收集实例对象。但是,静态对象不会被完全垃圾收集。
至于问题的第二部分,延长生命周期的正确方法称为“赞助” - 基本上当租约到期时,服务器会询问客户是否有人愿意继续使用此对象。关于这个主题有一篇非常详细的文章here。不要只将寿命设置为无穷大。
答案 1 :(得分:3)
静态字段永远不会被垃圾收集。看看Jeffrey Richter's article 垃圾收集器将静态字段视为根,因此垃圾收集器将始终假定使用静态字段。
加载所有者类型时会初始化静态字段。 JIT编译器在需要构建方法时加载类型,并看到对此类型的引用。加载后,类型将保留所有AppDomain生命周期,因此属于该类型的字段(静态字段)引用的任何内容都将被视为已使用的引用,并且不会被垃圾回收。
另外,关于这个陈述:
我无法找出生命的一生 他们得到这些静态变量 created(运行静态构造函数) 当他们第一次接触时 时间。
技术上静态变量不一定在静态构造函数中第一次“触及”。考虑这样的类:
public static class Test
{
private static MyType myType;
static Test()
{
myType = new MyType();
}
}
永远不会调用静态构造函数(类型构造函数),除非您拥有正在执行并引用此类型的代码,如var x = Test.myType;
。嗯,这可能取决于“触及”的确切含义。
答案:
静态类型存在于AppDomain中,因为它们是第一次访问,直到卸载AppDomain。因此,只要AppDomain正在运行,您就不需要延长其生命周期。