[翻譯] 編寫高性能 .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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...