2011-05-24 48 views
6

我很好奇在AppDomain中的共享/靜態對象生命週期,其中RemotingCalls是創建共享對象的原因。客戶端激活對象在應用程序域中靜態對象的遠程處理壽命

我們正在使用遠程處理設置,它使用客戶端激活的對象,我們只使用函數來訪問服務器。遠程對象被設置爲單例。

服務器設置一個通道並使用RemotingConfiguration.Configure加載配置文件。

其中一些服務器功能在服務器上觸及並使用一些靜態(在vb.net中共享)變量。我找不到這些靜態變量的生命週期是什麼,它們在第一次被觸及時被創建(靜態構造函數正在運行)。使用日誌記錄我看不到對象處置/最終發生。

連接到遠程處理服務器後等待幾分鐘,可以看到共享對象仍然活着。

問題:

那麼,什麼是在這個遠程設置靜態對象的預期生存時間。它們的壽命是否與AppDomain一樣長,或者當Remoting對象交換時它們是否會被循環使用。如果需要,延長壽命的正確方法是什麼?

答案:

靜態類型住的AppDomain,因爲他們首次訪問的,直到應用程序域被卸載。所以,只要AppDomain正在運行,您就不需要延長它們的生命週期。

回答

3

靜態字段永遠不會垃圾收集。看看Jeffrey Richter's article
垃圾收集器將靜態字段視爲根,所以垃圾收集器將始終假定使用靜態字段。

當所有者類型被加載時,靜態字段被初始化。 JIT編譯器在需要構建方法時加載類型,並看到對此類型的引用。一旦加載,類型將保留在AppDomain的所有壽命中,因此屬於該類型的字段(靜態字段)所引用的任何內容都將被視爲使用的引用,並且不會被垃圾收集。

此外,關於這樣的說法:

我無法找出 這些靜態變量的壽命,他們得到 創建(靜態構造函數運行) 時,他們動真情第一個 時間。

技術上靜態變量在靜態構造函數中不一定是「觸及」的。考慮這樣的類:

public static class Test 
{ 
    private static MyType myType; 

    static Test() 
    { 
     myType = new MyType(); 
    } 
} 

靜態構造函數(類型構造)將不會被永遠叫,除非你有正在執行和引用這種類型的像var x = Test.myType;的代碼。那麼,這可能取決於什麼「感動」的意思。

答案:

靜態類型住的AppDomain,因爲他們首次訪問的,直到應用程序域被卸載。所以,只要AppDomain正在運行,您就不需要延長它們的生命週期。

+0

靜態對象被垃圾收集器視爲根的事實永遠不會被GC'ed,這是永遠不會忘記的事情。 – CodingBarfield 2011-06-01 12:57:43

5

遠程處理對象直到租約到期後才被垃圾收集 - 租約可以保護它們免受GC影響,因爲它們沒有明顯的可見參考。默認的租約期限是5分鐘,垃圾收集器可能會在另外幾分鐘內運行(取決於負載,內存使用情況等),然後最後一次對象的引用應該消失。只有在發生這一切後,才能在下一個 GC運行中收集實例對象。然而,靜態物體將不會被垃圾收集完全在

至於問題的第二部分,延長壽命的正確方法稱爲「贊助」 - 基本上當租約到期時,服務器詢問客戶是否有人願意繼續使用此對象。關於這個主題here有一篇非常詳細的文章。不要只將壽命設置爲無窮大。

+0

我讀過這篇文章,但這更多的是關於主機進程然後Remoting類。 Marshall By Reference對象被及時收集,但我對共享/靜態對象感到好奇。觸發GC集合似乎沒有清理靜態對象。 – CodingBarfield 2011-05-30 13:29:13

+1

我發現了其他東西 - 靜態類似乎並不是垃圾收集**。 Google:c#靜態類垃圾回收 – 2011-05-30 14:24:04

相關問題