2010-06-25 53 views

回答

15

否 - 更改爲靜態方法對內存沒有影響。

第一次引用類型(無論是靜態還是非靜態),將初始化任何靜態成員並運行靜態構造函數。但是,如果您只是考慮將方法從非靜態方式切換到靜態方式,這將對垃圾回收或總內存佔用情況沒有影響。

如果將類成員更改爲靜態成員,則只需要擔心內存佔用情況發生變化。在這種情況下,一旦類型被訪問,靜態字段將保持爲根,並且不會被GC收集。這通常只在必要時完成,並且通過設計 - 您將會員設置爲靜態,因爲您希望會員持續存在。

+0

是否存在存儲在任何位置的靜態方法的副本?我的假設是,當你引用一個靜態方法時,它將被存儲在某個地方,然後每個後續引用都會使用該方法的實例,但我知道這個假設可能是錯誤的。 – 2010-06-25 17:38:09

+3

無論是靜態還是實例方法,「方法」在進入進程空間時都會在內存中加載一次,並由JIT編譯。靜態和非靜態方法使用方面確實沒有區別。關注靜態方法是否適合您的特定情況 - 並用它來確定方法應該是靜態方法還是實例方法。 – 2010-06-25 17:40:30

+0

對內存的影響非常小 - 因爲會生成額外的代碼來將「this」指針傳遞給不使用它的方法。 – Qwertie 2010-06-25 18:21:32

7

從JIT編譯器的角度來看,靜態方法和實例方法沒有區別。他們的機器代碼非常相似,它被存儲在同一種堆中。唯一的區別是一個實例方法有一個額外的參數。

該方法被調用時需要傳遞額外的參數。這會花費額外的機器碼指令,但並不經常。 CPU寄存器(ECX)經常具有正確的值。如果一個實例方法在x86上有多個參數或在x64上有三個以上參數,則有一個區別,必須在堆棧上傳遞額外的參數,而不是通過CPU寄存器。一個額外的指令。

最糟糕的情況是,你正在看的不到一納秒。這將很難衡量,這是微型優化的常見問題。

+0

這可能超出了原始問題的範圍,但是在調用靜態方法或不調用方法時存儲在堆上的內容是什麼?它只是方法本身,還是包含方法的類的實例,或者其他什麼? 垃圾收集是否收集過這種記憶? – 2010-06-25 18:24:36

+0

在方法調用期間沒有任何東西存儲在堆上。參數通過CPU寄存器和堆棧傳遞。什麼都不需要收集。 Petzold的書「代碼」可能會讓你感興趣。 – 2010-06-25 18:40:37

+0

好吧,這很有道理。所以真的,將我的方法從非靜態轉換爲靜態的唯一原因是在沒有類實例的情況下訪問它們?感謝您的推薦。 – 2010-06-25 18:44:37

相關問題