2012-08-25 30 views
1

讓我們這個例子中,我想蓋我的所有問題:靜態屬性/方法的內存分配

class SomeClass 
{ 
    static SomeType PropertyA 
    { 
     get 
     { 
      if (....) 
       return MethodA(); 
      else 
       return MethodB(); 
     } 
    } 

    static SomeType MethodA() { ... } 
    static SomeType MethodB() { ... } 
} 

將調用SomeClass.PropertyA屬性創建一個內存泄漏?我的意見不是,因爲財產本身沒有支持領域,這會造成內存泄漏。我問這是因爲我已經讀過靜態屬性可以創建內存泄漏,但我認爲它是負責內存泄漏的後臺字段,因爲它擁有對實例的引用。

所以在上面的例子中,上面例子中的MethodA,MethodB和PropertyA不應該產生任何內存泄漏。我錯了嗎?

我的另一個問題是:我有很多類,大多沒有狀態和數據。他們只是充當代理人。其中一些方法非常頻繁地被調用。我的問題是:我應該讓這些類是單獨的,靜態的還是常規的類?

完美的例子將是一個包含5-10個方法的類,並執行一些SQL查詢。 1)如果我將它們定義爲常規,那麼我需要經常創建它們(在某些用戶反應中),調用某種方法,然後允許垃圾收集。

2)選擇單身還是靜態,會有哪些優點/缺點? 3)如果我有一個包含代理方法的類,但有2-3個包含10個參數的IDbCommands,並且有利於重用它們,那麼這會改變選擇正確模式的任何內容嗎?

編輯:由於我得到了一些讓我更困惑的答案,可能是由於誤解,我會發布第一個問題的答案。我做了一個測試,在那裏我分配了一個大的字節數組(300MB),它通過PropertyA(和MethodA)獲取。 上述示例中的PropertyA abd MethodA都不會在獲取該對象後對其進行引用,因此只要調用代碼與數組完成,它將由GC處理。因此,如果我們只使用靜態屬性或者使用靜態方法,則不應該有任何內存泄漏。

回答

1

所以在上面的例子中,上面例子中的MethodA,MethodB和PropertyA不應該產生任何內存泄漏。我錯了嗎?

如果您的意思是他們不會創建或保留任何內存,那麼這是真的 - 屬性本身不會保留內存。

靜態字段不會創建「內存泄漏」 - 該類型的類型初始值設定項將在首次使用該類之前運行,並且如果某個字段需要內存,則將分配該字段的內存。這個內存不會被清除 - 如果這就是你的意思所謂的「泄漏」 - 但是沒有實例可以釋放,所以這是預期的和期望的行爲。

+0

我已經更新了這個問題來解釋我的意思是內存泄漏。當你說「如果一個字段需要內存,該字段的內存將被分配」,這是否意味着SomeProperty不會包含對SomeClass的引用(在我的第一個示例中)? – Goran

+0

@Goran是的,如果「MethodA」或「MethodB」不返回null,當然。但是,是的,這個字段將會引用該實例,並且這將保持垃圾收集的參考。 –

+1

所以,這是一個內存泄漏,這意味着我已經提出的上面的代碼是錯誤的代碼,並且不應該被使用。每次調用PropertyA都會返回不同的實例。這意味着當調用代碼完成對SomeClass實例的使用時,此實例將永遠不會被收集(PropertyA引用它),但同時此對象不再可訪問,因爲對PropertyA getter的調用將返回對SomeClass的新實例。 – Goran

0

簡單的答案是一個問題:「這些方法做了什麼,它們是否保持狀態,並且它們是否具有或不具有簡單垃圾回收之外的清理要求?」

如果他們不對所有上述情況,理由是你不會有泄漏。只有當你不做任何事情時纔會發生泄漏,如果你沒有做任何事情需要採取任何行動,你就沒有泄漏。

現在它更多的是關於「內存壓力」而不是泄漏。

一般來說,我會傾向於實例方法,因爲它提供了垃圾回收功能,可以更容易地模擬和測試場景。

靜態方法和變量受到與實例變量和方法相同的問題,因此如果可能的話,泄漏適用於兩者。

+0

這個問題本身對你的問題有一個答案:它們只是代理方法,它們沒有狀態,也沒有數據。這(第二個)問題與內存泄漏無關,但僅與使用哪種模式有關。那麼,你的建議是把所有東西都當成普通班級,每次需要時重新創建它們? Singleton類也準備測試嘲笑(它的一個(單個)實例類),那麼爲什麼不把它當作單例呢? – Goran

+0

我想我的答案是這樣的:如果你的整個鏈的屬性和方法沒有任何狀態(你說他們沒有),那麼是的,你沒有內存泄漏。如果鏈狀態中的任何地方保持不變,那就是狀態沒有被覆蓋,但在運行時調用時添加了狀態(例如,代碼中的某些副作用會將事件附加到靜態列表中,然後即使發生泄漏以上都是靜態的)。 – Kit