[翻譯] 編寫高性能 .NET 代碼--第二章 GC -- 配置選項

来源:http://www.cnblogs.com/yahle/archive/2017/05/28/6915751.html
-Advertisement-
Play Games

在基於“less rope to hang yourself with”思想下,.NET 框架沒有給開發提供很多太多的配置選項。但在大多數情況下,GC會跟你的硬體配置,及可用資源以及程式自己的行為做調整。當然也提供一些高級的配置使用,但這取決於你程式的類型。 ...


配置選項

在基於“less rope to hang yourself with”思想下,.NET 框架沒有給開發提供很多太多的配置選項。但在大多數情況下,GC會跟你的硬體配置,及可用資源以及程式自己的行為做調整。當然也提供一些高級的配置使用,但這取決於你程式的類型。

工作站與伺服器

你首要的是為應用選擇是在工作站還是伺服器模式下運行。

系統預設為工作站模式。在這種模式下,GC在觸發回收時,回收線程與當前主線程的優先順序一樣。對於簡單的應用程式,特別是存在工作站里有多個托管進程需要做交互的情況下,以及單處理器的電腦上,這可能是唯一的選擇,你試圖修改任何配置對運行不會產生任何影響。
伺服器模式則會給每個業務邏輯進程創建一個專用的線程。這個線程會運行在高優先順序(THREAD_PRIORITY_HIGHEST),但平時這個線程會處於休眠狀態,一旦需要做GC就會被喚醒。完成GC後又會進入休眠。

此外,CLR還會為每個處理器分配一個單獨的堆。每個處理器堆里,包含一個小對象堆和大對象堆。從你的應用程式角度上看,你的代碼不知道引用的對象是屬於哪個堆上面的(他們都有相同的虛擬地址空間)。

使用多個堆有下一些優點

  1. 垃圾回收可以並行處理。每個GC線程處理一個對應的堆。這是的伺服器模式的GC比工作站模式要快的原因。
  2. 某些情況下,分配速度會更快,尤其是將大對象相對分配在同一個堆上快。還有一些其他內部差異,比如記憶體段的大小,越大的段在做垃圾回收時時間也會越長。

你可以在App.config 文件里的節點里配置。

<configuration>
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

你要如何選擇工作站或者伺服器模式嗎?
如果一個多處理器機器上只運行你的應用程式,那麼最明智的選擇是:伺服器模式。它在大多數情況下可以降低GC的延遲。
另一位方面,如果你的機器有多個托管進程的應用程式,則需要具體分析了。如果這幾個托管應用都採用伺服器模式,那麼會創建很多個高優先順序的線程,這個會對線程調度產生衝突和影響。在這種情況下,最好使用工作站模式。
如果你真的想在同一個台機器里的多個應用程式開啟伺服器GC模式,還有另外一種選擇,就是為應用程式綁定特定的CPU。
無論你選擇哪種模式,本書的大部分技巧都使用這兩種模式。

後臺GC

修改後臺GC配置會更改2代對象的回收策略。相對於0代和1代的回收的前臺GC,它不會中斷當前應用里其他的線程執行。
後臺GC在會而外創建一個線程用來處理2代對象的回收。這意味著,如果你同時開啟後臺GC和伺服器GC,你將為每個處理器創建2個線程來處理GC。但這沒啥大不了的,雖然進程里多了很多個線程,但這些線程在大部分時間里還是不工作的。
在你的應用執行的時候GC也可以同時進行,但在某些情況下,還是會發生阻塞。在這時,後臺GC還是會將應用程式里的其它線程給掛起。
如果使用工作站模式,則始終開啟後臺GC模式,從.NET4.5開始,預設情況下伺服器GC模式下也會開啟,當然你也可以關閉它。
以下是關閉後臺GC的配置

<configuration>
    <runtime>
        <gcConcurrent  enabled="false"/>
    </runtime>
</configuration>

實際上,我們很少有理由去禁用後臺GC。如果你想通過禁用後臺GC的線程來提高你的應用程式在CPU的占用率,但這個想法是不現實的。但如果是減少GC的延遲或者頻率可以考慮關閉它。

低延遲模式

如果你的應用希望在一段特定時間里高速執行,不希望被GC的2代回收打擾。你可以通過改變 GCSettings.LatencyMode 的設置來實現。

LowLatency—只能在工作站模式運行,它可以暫停2代回收。
SustainedLowLatency—可以在工作站和伺服器模式下執行。它可以暫停完整的2代回收,但如果你開啟里後臺GC模式,你還是可以在後臺GC線程里對2代對象做回收。

這兩種模式都將大大的增加記憶體的消耗,因為它沒對記憶體做壓縮。如果你的應用需要消耗大量的記憶體,則最好避免開啟這兩個模式。

當你要準備進入低延遲模式前,最好手動執行一次完整的GC(GC.Collect(2, GCCollectionMode.Forced)。等離開低延遲模式後,也手動觸發一次完成GC。
預設情況下,是不需要開啟這個模式。只有你的程式執行時間不要被GC打擾才需要開啟,不用在全過程都開啟。舉個慄子:如果你有一個股票交易的高頻應用,在交易時間段里不希望發生GC回收暫停應用執行。但在股市交易結束後,你可以關閉這個模式進行完整的GC回收直到股市重新開市。

如果要開啟低延遲模式,至少要符合以下標準:

  1. 在正常執行期間,完整的垃圾回收操作是不可接受的
  2. 應用程式消耗的記憶體要遠小於可分配記憶體
  3. 應用程式在開啟低延遲模式後,要有足夠的記憶體撐到下一次手動執行完整回收或者重啟。

這是一個很少用的配置,如果你要使用請三思而後行,因為開啟之後會出現一些意想不到的後果。如果你認為還是有必要使用,請確保你的應用經過了充分測試。在開啟後,系統會產生更頻繁的0代和1代的回收操作,用來減少完整的回收,這可能會導致一些其他性能問題。這可能會導致解決了一個又另外產生了一個問題。

最後,請註意,低延遲模式不是一個保證。如果GC在做回收的時候仍然拋出了OutOfMemoryException異常,仍然有可能會不管你的配置選項,進行一次完整的GC回收。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天因為C盤的記憶體變得不夠多而再次選擇了重裝系統,重裝系統,win7的重裝系統的映像網址為:http://win.njbda.cn/win7.html 我選擇的是“雨林木風”的64位系統,那麼問題來了,每個人的電腦本機系統不同,那麼我們需要根據自己的系統進行對win7的下載,那麼,如果像我一樣不記得 ...
  • 簡介 sed 是一種線上編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩衝區中,稱為“模式空間”(pattern space),接著用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。接著處理下一行,這樣不斷重覆,直到文件末尾。文件內容並沒有 改變,除非你使用重定向存儲 ...
  • 方法有二: 1、臨時開啟(重啟即失效) echo 1 > /proc/sys/net/ipv4/ip_forward 或 vim /proc/sys/net/ipv4/ip_forward,將0修改為1,保存退出 2、永久開啟 sed -i 's/net.ipv4.ip_forward = 0/ne ...
  • 閱讀目錄 1. 介紹 2. 軟體準備 3. 建立SVN Server倉庫 4. 配置安裝PHP&IF.SVNadmin 5. 啟動服務 1.介紹 公司最近想把Windows server平臺的SVN遷移到Linux平臺;這邊經過測試成功,所以寫個隨筆記錄一下 今天寫的是CentOS7上搭建基於Apa ...
  • 1.Lazy<T>的使用 無意間看到一段代碼,在創建對象的時候使用了Lazy,顧名思義Lazy肯定是延遲載入,那麼它具體是如何創建對象,什麼時候創建對象了? 先看這段示列代碼: 使用非常簡單,把 OrderService 放到Lazy<T> 中,然後 _orderSrv.Value 的時候才真正創建 ...
  • 一般拿Timer和Quartz相比較的,簡直就是對Quartz的侮辱,兩者的功能根本就不在一個層級上,如本篇介紹的Quartz強大的集群機制,可以採用基於 sqlserver,mysql的集群方案,當然還可以在第三方插件的基礎上實現quartz序列化到熱炒的mongodb,redis,震撼力可想而知 ...
  • C# 7.0已經出來一段時間了,大家都知道新特性裡面有個對元組的優化:ValueTuple。這裡利用詳盡的例子詳解Tuple VS ValueTuple(元組類VS值元組),10分鐘讓你更瞭解ValueTuple的好處和用法。 如果您對Tuple足夠瞭解,可以直接跳過章節”回顧Tuple”,直達章節 ...
  • 最近需要做一個列印的功能,於是在網上找到了這麼一個方法。 以上就是全部代碼了,調用就很簡單了,方法如下: ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...