2010-07-21 18 views
4

假設我們有一個具有10000個常量字符串成員的類。CLR:內存中常量字符串值的生存期是多少?

class Schema 
{ 
    //Average string length is 20 
    public const string ID1 = "some.constant.value"; 
    public const string ID2 = "some.other.constant.value"; 
    //... 
} 

並非所有的字段在其餘的代碼中被引用。其中只有10%是在啓動時訪問的 - 它們的引用被指定爲各種字典(數千字典實例)的關鍵字。我知道const字符串是被interned的 - 多次引用一個const字符串不會增加消耗內存的多於指向interned字符串表中偏移量的元數據標記的大小。

據我所知,常量字符串被編譯到程序集中,從而影響編譯程序集的大小。


這些const字符串在什麼確切時間/事件中佔用運行時內存?

將所有內存所需的所有常量字符串採取在程序集加載或這是延遲,直到類是JIT編譯?

我們可以通過改變等式中的某些東西來減少啓動後的內存消耗嗎? (使字段非常量,使字符串靜態字段?)。

讓我們假設一個Winforms應用程序(.NET 2.0)。

+2

作爲一個粗略的猜測,總內存消耗大約爲300 kB,大約是現代計算機RAM(4 GB)的0.0075%。這有多重要? – 2010-07-21 11:42:42

+1

忘記數字,內存使用優化不是這裏的目標。這個問題主要是爲了理解原理而提出的。 – Marek 2010-07-21 11:45:51

+0

@Marcelo:RAM和它有什麼關係? RAM是性能優化;恐慌資源不是RAM,它是虛擬地址空間。當你「內存不足」時,你已經用完了地址空間,而不是RAM;如果你的內存不足,那麼操作系統就會進入磁盤並對其進行分頁。現在不再是1980年了;我們有虛擬內存。 :-) – 2010-07-21 14:23:12

回答

3

Const字符串是編譯時文字,並且由於CLR使用這些實例,只要應用程序處於活動狀態,它們就會一直存在。

您也可能會找到我的答案this question相關。

0

我可能是錯的,但是當程序集第一次被引用時,它全部加載到內存中,其中包含所有代碼,元數據和常量值(我不確定嵌入式資源是否也被加載或延遲)。它會一直加載,直到過程終止。

+0

@亨克我明白了。但問題是它是按需加載的。整個集會(我的)或只是一點點? – 2010-07-21 12:42:58

+0

只需要它的位。 – 2010-07-21 13:04:09

0

字符串是常量並不重要。常量本身並不佔用任何內存,它是佔用內存的字符串。

當您在代碼中使用常量時,編譯器會將其替換爲對文字字符串的引用。

字符串文字用程序集加載,所以它們在整個應用程序的整個生命週期中都存在。即使您將常量改爲其他字符,字符串文字仍然存在。使用變量而不是常量實際上會使用更多的內存,因爲它需要某處存儲變量的值(即對文本字符串的引用的副本)。

+0

所以你建議如果我不使用代碼中的任何常量,它們將不會記憶任何內存? – Marek 2010-07-21 11:49:25

+0

@Marek:字符串仍然佔用內存,編譯器無法優化它們。常量(即對文字字符串的引用)是在編譯時使用的聲明,它們從不佔用任何內存。 – Guffa 2010-07-21 11:53:34