2013-07-19 32 views
0

當CLR執行垃圾收集時,它也會壓縮堆。現在,如果CLR沒有使用連續的內存塊,它不能擺脫它們之間未使用的空間,而是一起按對象,是否正確?CLR是否佔用連續的內存塊?

但是,如果那是真的,那麼會出現另一個問題。如果由CLR運行的進程需要比CLR當前佔用的內存更多的內存,那麼CLR如何確保新佔用的內存與CLR當前保留的內存連續?可能是內存已被非clr進程使用。因此,可能的內存不連續到已經被CLR佔用的內存。所以現在CLR在兩個不連續的內存之間工作,在那種情況下壓實會如何工作? 「

回答

2

這只是不是如何工作。 CLR以大塊分配虛擬內存空間,稱爲,底層winapi調用爲VirtualAlloc()。它曾經分配的最小部分是兩兆字節。如果程序快速消耗內存,它會詢問更大的內存。

GC僅壓縮段的內容。沒有必要在地址空間中使這些段自身連續。 CLR不得不處理不僅用於GC數據而且用於代碼和其他堆的地址空間。包括爲非託管代碼和數據進行的分配。典型的託管程序至少有10個不同的堆。其中之一是大對象堆,GC用於大型對象的那個大對象,因爲移動它們太昂貴,所以沒有壓縮。只有小於85,000字節的對象纔會在代碼堆中結束並被壓縮。

壓縮有助於避免碎片並提高L1緩存的使用率。一個片段不能大於85,000字節,L1數據緩存通常是32,768字節。兩者都遠低於最小的細分市場。

1

」可能是內存已被非clr進程使用。「

該CLR旨在運行在現代計算機上。它們具有虛擬地址空間,即每個進程都有其自己的連續地址空間。內存可能是物理交錯的,但不是邏輯上的。

不過,分配的內存可能會被分割。這不是什麼大不了的事。對於初學者來說,有兩堆(小物體/大物體),小物體堆分成3代。所以你不需要爲此分配一個單獨的分配。

壓實不保留順序。如果有16個字節的空洞,將所有對象向下移動16個字節將會非常昂貴。相反,可以從任何地方將單個對象移動到洞中 - 理想情況下是從未使用的頁面移動到洞中,以便可以回收。