相信很多人面試的時候都聊過GC,關于GC的回收也都看過相關的一些文章,比如:
什么時候發生GC
1、當應用程式分配新的物件,GC的代的預算大小已經達到閾值,比如GC的第0代已滿;
2、代碼主動顯式呼叫System.GC.Collect();
3、其他特殊情況,比如,windows報告記憶體不足、CLR卸載AppDomain、CLR關閉,甚至某些極端情況下系統引數設定改變也可能導致GC回收。
這個說法來自于微軟相關文章的翻譯,關于第1種情況的閾值,解釋非常籠統非常抽象,沒有給出具體的值、如何配置等等,比如我寫一個程式運行中如何知道什么時候達到了閾值觸發了回收。
那么問題來了,.net是基于托管的語言,GC的回收觸發時機又是非常模糊和不確定,關注GC的意義在哪里?
是否做好非托管資源(檔案、資料庫連接等)的釋放是不是就足夠了?
uj5u.com熱心網友回復:
.net很少關注,但是如果與非托管代碼一起開發就得考慮了.這種非常討厭,各種惡心uj5u.com熱心網友回復:
非托管代碼不屬于GC的一畝三分地,它想管也管不了吧
uj5u.com熱心網友回復:
就跟你裝行車記錄儀的作用一樣。雖然平時他幾乎沒啥作用。但真出事的時候,你就知道他有用了和那個園子不同,其實真正開發是不管的。也就是那個園子的人喜歡吹吹NB,覺得會gc了就能把HR和面試管給侃暈了
其實真實的情況是,如果我知道門不夠寬(記憶體不夠),那么你能做的只有兩件事情
1.排好隊,別插隊,別爭搶
2.每個人都給我快速過去,別堵門。(大任務都給我拆小了,能快速平穩過去,比你天天想著怎么造個更結實的門有用)
so,你瞧我們討論GC么,那些個吹NB說一個gc如何如何血案的,其實把原因很簡單,他們只想怎么把門弄結實了,結果是你在結實的門,也經不住瘋狂的沖撞和某個人就是不過去,他就堵著門。ok,血案發生,so,繼續找個更結實的門去把
uj5u.com熱心網友回復:
關于閾值這個問題,閾值有閾值的上下限和閾值系數的上下線
第0帶的閾值下限位0,上線也為6MB左右
第1代的閾值下限位160KB,上限無限制
第二代的閾值下限為 256kb,上限無限制
第二代大物件閾值下限為3MB,上線無限制
至于系數嘛,由于第0代區分服務器和作業戰模式所以分別為(20,10以及9,20) 其余代
上下限以及12代大小物件的分別為(2,7 ---1.2f,1.8f--- 1.25f,4.5f)
由于每次觸發一次GC回收都會新計算分配量,分配量是根據系數以及上次分配量來計算,頂值不超過上面的數值。超過了就觸發物理記憶體不足,同樣導致再次GC。
具體計算方法如下:
float allocation_fraction = (float) (dd_desired_allocation (dd) - dd_gc_new_allocation (dd)) / (float) (dd_desired_allocation (dd));//計算偏移率
cst = min (1.0f, float (out) / float (dd_begin_data_size (dd)));//計算存活率,GC結束后該代存活物件大小/開始前該代存活物件大小
f = surv_to_growth (cst, limit, max_limit); //計算閾值增長系數
if ((allocation_fraction < 0.95) && (allocation_fraction > 0.0))//當偏移率大于0 小于0.95
{
// 新分配量閾值= 偏移率* 新分配了閾值 + (1.0 - 偏移率)* 就分配了閾值
new_allocation = (size_t)(allocation_fraction*new_allocation + (1.0-allocation_fraction)*previous_desired_allocation);
}
uj5u.com熱心網友回復:
不需要太糾結垃圾自動回收這個東西吧~C#的垃圾自動回收通俗一點理解:你在一個地方扔垃圾,不需要你撿起來扔進垃圾桶,因為會有人定期來打掃。而類似C++這樣的語言,自己扔了垃圾(new)必須趕緊自己撿起來扔掉(delete),就是這么個區別。對于非托管的資源,諸如檔案流、資料庫連接之類的操作,也只需要用using括起來就行了。轉載請註明出處,本文鏈接:https://www.uj5u.com/net/245462.html
標籤:C#
下一篇:帆軟bi報表單元格出現空白行解決
