簡體   English   中英

短暫的對象

[英]Short-lived objects

生成大量“年輕”(在垃圾收集間隔期間從未提升到下一代)的臨時對象(即用於臨時結果)的開銷是多少? 我假設“新”操作非常便宜,因為它實際上只是一個指針增量。 然而,處理這些臨時“垃圾”的隱性成本是什么?

不是很多——垃圾收集器對於 gen0 來說非常快。 它還會自行調整,根據每次運行時設法收集的數量來調整 gen0 的大小。 (如果設法收集很多,它將減小 gen0 的大小以便下次更早收集,反之亦然。)

最終的測試是您的應用程序的性能如何。 Perfmon 在這里非常方便,顯示在 GC 上花費了多少時間,每一代都有多少 collections 等等。

正如您所說,分配本身非常便宜。 生成大量短期對象的成本是更頻繁的垃圾 collections,因為它們是在第 0 代的預算用盡時觸發的。 但是,第 0 代集合相當便宜,因此只要您的 object 確實是短暫的,那么開銷很可能並不顯着。

另一方面,在循環中連接大量字符串的常見示例會顯着推動垃圾收集器,因此這完全取決於您創建的對象數量。 考慮分配並沒有什么壞處。

垃圾回收的代價是托管線程在壓縮期間被掛起。

一般來說,這不是你應該擔心的事情,聽起來它開始非常接近“微優化”。 GC 的設計假設一個“調整良好的應用程序”將在 Gen0 中擁有所有分配 - 這意味着它們都“年輕而死”。 任何時候你分配一個新的 object 它總是在 Gen0 中。 在通過 Gen0 閾值並且 Gen0 中沒有足夠的可用空間來容納下一次分配之前,不會發生收集。

“新建”操作其實是一堆東西:

  1. 分配 memory
  2. 運行類型構造函數
  3. 返回指向 memory 的指針
  4. 遞增下一個 object 指針

盡管新操作的設計和編寫效率很高,但它不是免費的,並且確實需要時間來分配新的 memory。 memory 分配庫需要跟蹤哪些塊可用於分配,並且新分配的 memory 被歸零。

創建大量年輕時死亡的對象也會更頻繁地觸發垃圾收集,並且該操作可能會很昂貴。 尤其是“停止世界”垃圾收集器。

這是 MSDN 上關於其工作原理的文章: http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

注意:它描述了調用垃圾回收是多么昂貴,因為它需要在開始垃圾回收之前構建 object 圖。

如果這些對象從未從第 0 代中提升出來,那么您將看到相當不錯的性能。 我能看到的唯一隱藏成本是,如果您超出第 0 代預算,您將強制 GC 壓縮堆,但 GC 會自我調整,所以這不是什么大問題。

垃圾收集在.Net 中是世代相傳的。 短暫的物體將首先且頻繁地收集。 Gen 0 集合很便宜,但根據您創建的對象數量的規模,它可能非常昂貴。 我會運行一個分析器來確定它是否會影響性能。 如果是,請考慮將它們切換為結構。 這些不需要收集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM