Net內存管理五大基礎
1.小對象怎麼處理的?
小型.NET
對象被分配到小型對象堆(SOH
)上。其中有3種:第0代,第1代和第2代。對象根據其壽命向上移動。
將新對象放在Gen 0上。當Gen 0充滿時,.NET垃圾收集器(GC)運行,處理不再需要的對象,並將其他所有內容移至Gen1
。如果Gen 1充滿,則GC再次運行,也可以將Gen 1中的對象移動到Gen 2中。
當Gen 2
變滿時,將發生GC
完全運行。這將清除不需要的Gen 2
對象,將Gen 1
對象移至Gen 2
,然後將Gen 0
對象移至Gen 1,最後清除所有未引用的內容。每次運行GC
之後,都會壓縮受影響的堆,以將仍在使用的內存保持在一起。
這種代代相傳的方法可確保事情高效運行-耗時的壓縮過程僅在絕對必要時才會發生。
註意:如果您在Gen 2
中看到大量的內存,則表明內存已被保留很長時間,並且可能存在內存問題。這是內存分析工具可以派上用場的地方。
2.較大的對象會怎樣?
大於85 KB
的對象被分配到大對象堆(LOH
)。由於復制大塊內存的開銷,它們沒有被壓縮。當發生完整的GC
時,未使用的LOH
對象的地址范圍將記錄在可用空間分配表中。
分配新對象後,將在此可用空間表中檢查足以容納該對象的地址范圍。如果存在,則將對象分配到那裡,如果不存在,則將對象分配到下一個可用空間。
由於對象不太可能是空地址范圍的確切大小,因此對象之間幾乎總是會留有小塊內存,從而導致碎片。如果這些塊小於85 KB
,則根本沒有重用的可能性。因此,隨著分配需求的增加,即使碎片空間仍然可用,也會保留新的段。
此外,當需要分配大對象時,.NET還是傾向於將對象附加到末尾,而不是運行昂貴的Gen 2 GC
。這對性能有好處,但是是導致內存碎片的重要原因
3.垃圾收集器可以在不同的模式下運行以優化性能
.NET通過為GC
提供多種模式來解決性能與堆效率之間的權衡問題。
工作站模式為用戶提供瞭最大的響應速度,並減少瞭由於GC造成的暫停。它可以作為“並發”或“非並發”運行,指的是運行GC
的線程。默認值為並發,它為GC使用單獨的線程,因此應用程序可以在GC
運行時繼續執行。
服務器模式可為服務器環境提供最大的吞吐量,可伸縮性和性能。在服務器模式下,段大小和生成閾值通常比工作站模式大得多,這反映瞭對服務器的更高要求。
服務器模式在多個線程上並行運行垃圾回收,為每個邏輯處理器分配一個單獨的SOH和LOH,以防止線程相互幹擾。
.NET
框架提供瞭一種交叉引用機制,因此對象仍然可以在堆之間相互引用。但是,由於應用程序響應能力不是服務器模式的直接目標,因此在GC期間,所有應用程序線程都將被掛起。
4.引用不足會在性能和內存效率之間折衷
弱對象引用瞭GC
根的替代來源,使您可以保留對象,同時在GC需要時可以收集對象。它們是代碼性能和內存效率之間的折衷。創建對象需要占用CPU
時間,但保持加載狀態需要占用內存。
弱引用特別適用於大型數據結構。例如,假設您有一個允許用戶瀏覽大型數據結構的應用程序,他們可能會返回其中的一些數據。您可以將任何強引用轉換為他們瀏覽的結構為弱引用。如果用戶返回到這些結構,則可以使用它們,但如果沒有,GC可以根據需要回收內存。
5.對象固定可以創建在托管和非托管代碼之間傳遞的引用
.NET
使用一種稱為GCHandle
的結構來跟蹤堆對象。GCHandle
可用於在托管域和非托管域之間傳遞對象引用,.NET維護一個GCHandles
表以實現此目的。GCHandle
有四種類型,包括固定的,用於將對象固定在內存中的特定地址。
對象固定的主要問題是它可能導致SOH
碎片化。如果將對象固定在GC
期間,則根據定義,該對象無法重定位。根據您使用固定的方式,它會降低壓縮的效率,在堆中留下間隙。避免這種情況的最佳策略是在很短的時間內鎖定,然後釋放。
到此這篇關於Net內存管理五大基礎的文章就介紹到這瞭,更多相關Net內存管理五大基礎內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 解決net start MongoDB 報錯之服務名無效的問題
- .NET Core、Xamarin、.NET Standard和.NET Framework四者之間的區別介紹
- 關於net 6+vue 插件axios 後端接收參數問題
- .Net RabbitMQ實現HTTP API接口調用
- .Net Core讀取文件時中文亂碼問題的解決方法分享