工具出現掛死問題,巡檢IIS發現如下異常日誌html
現網系統日誌:安全
事件類型: 錯誤服務器
事件來源: .NET Runtime架構
描述:併發
Application: DiyRingSet30Tool.exe工具
Framework Version: v4.0.30319性能
Description: The process was terminated due to an internal error in the .NET Runtime at IP 791F7E06 (79140000) with exit code 80131506.優化
說明:此日誌能夠經過「開始」-「全部程序」-「管理工具」-「事件查看器」-「應用程序」,觀察類型爲錯誤或者警告的日誌,通常出現錯誤日誌都是應用程序錯誤致使的,請引發重視網站
在工具的配置文件中新增如下紅色的配置節點內容spa
<configuration>
<runtime>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>
緣由:正在引用的對象被取消引用由垃圾回收器在公共語言運行庫4(CLR4)中發生的問題。所以,垃圾回收或應用程序嘗試訪問已發佈的對象的過程當中發生訪問衝突。
垃圾回收器可自行優化而且適用於多種方案。 可基於工做負荷的特徵使用配置文件來設置垃圾回收的類型。 CLR垃圾回收能夠作內存移動也能夠不作移動。不作移動時也稱爲「清掃」,清掃的代價要比作壓縮的代價低一些,由於他不須要複製移動內存。CLR 提供瞭如下類型的垃圾回收:
1)工做站模式:關閉併發的工做站GC、開啓併發的工做站GC
2)服務器模式:服務器GC
工做站垃圾回收,用於全部客戶端工做站和獨立 PC。 這是運行時配置架構中的 <gcServer> 元素的默認設置。既能夠是併發的,也能夠是非併發的。 併發垃圾回收使託管線程可以在垃圾回收期間繼續操做。從 .NET Framework 4 開始,後臺垃圾回收取代了併發垃圾回收。
服務器垃圾回收,用於須要高吞吐量和可伸縮性的服務器應用程序。 服務器垃圾回收既能夠是非併發或後臺運行。
1) 關閉併發的工做站GC爲高性能服務器的高吞吐量作了優化。咱們在垃圾回收時根據分配和復活模式作動態調優所以能夠程序運行時自動調優GC的工做效率。
2) 開啓併發的工做站GC是爲要求精確響應時間的交互式應用程序設計的。開啓併發使垃圾回收形成的工做進程暫停時間縮短。 這個目的是用一些內存和CPU換來的,所以在這種模式下垃圾回收須要作的工做略多一點須要的回收時間會略長一些。
3) 服務器GC,從名字上咱們能夠看出這種工做模式是爲服務器應用程序設計的;典型的場景是你有一個工做線程池這些線程作着類似的處理。例如:作處理一樣的請求或者處理相同類型的事務。全部的線程使用幾乎相同的分配模式。服務器GC是爲要求高吞吐量的和高擴展性的多處理器服務器設計的
工做站模式(workstation mode) 。
1)這種模式下GC假設機器上運行的其餘應用程序對CPU資源要求不高,併發模式是默認的工做站模式,該模式下垃圾回收器分配一個額外的後臺線程在應用程序運行時併發回收對象。一個線程由於分配對象形成第0代超出預算時,垃圾回收器掛起全部線程(不會掛起運行本機代碼的線程、併發模式容許託管線程在回收期間運行),判斷須要回收哪些代,若是須要回收第2代,就會增長第0代的大小。而後應用程序恢復執行。
2)回收發生在觸發垃圾回收的用戶線程上,並保留相同優先級。 由於用戶線程一般以普通優先級運行,因此垃圾回收器(在普通優先級線程上運行)必須與其餘線程競爭 CPU 時間。
3)工做站垃圾回收始終用在只有一個處理器的計算機上,而無論 <gcServer> 設置如何。 若是你指定服務器垃圾回收,則 CLR 會使用工做站垃圾回收,並禁用併發。
服務器模式 (servermode)。
1)這種模式下GC假設機器上沒有運行其餘應用程序,全部的CPU均可以用來進行垃圾回收操做。在這種狀況下虛擬內存按照CPU數量劃分區域分開對待,每一個CPU上都運行一個GC線程負責回收本身的區域。 爲每一個 CPU 提供一個用於執行垃圾回收的一個堆和專用線程,並將同時回收這些堆。 每一個堆都包含一個小對象堆和一個大對象堆,而且全部的堆均可由用戶代碼訪問。不一樣堆上的對象能夠相互引用。
2)回收發生在以 THREAD_PRIORITY_HIGHEST 優先級運行的多個專用線程上。
3)由於多個垃圾回收線程一塊兒工做,因此對於相同大小的堆,服務器垃圾回收比工做站垃圾回收更快一些。
4)服務器垃圾回收一般具備更大的段。
5)服務器垃圾回收會佔用大量資源。 例如,若是在一臺具備 4 個處理器的計算機上運行了 12 個進程,則在它們都使用服務器垃圾回收的狀況下,將有 48 個專用垃圾回收線程。 在高內存加載的狀況下,若是全部進程開始執行垃圾回收,則垃圾回收器將要計劃 48 個線程。
併發垃圾回收
讓咱們從關閉併發的工做站GC提及,其執行流程以下:
1) 一個託管進程作內存分配
2) 分配完全部可用的內存
3) 觸發了垃圾回收,垃圾回收操做在作分配的線程上運行
4) GC調用SuspendEE來掛起全部的託管線程
5) GC開始工做
6) GC調用RestartEE來重啓工做託管進程
7) 託管進程繼續運行
圖:演示了在單獨的專用線程上執行的併發垃圾回收
你能夠看到在第5步中全部的託管線程都中止執行來等待垃圾回收完成工做。SuspendEE不會掛起本地線程(native threads)。
在開啓併發垃圾回收(Concurrent GC)時,最大的差別是掛起和重啓。併發垃圾回收經過最大程度地減小因回收引發的暫停,使交互應用程序可以更快地響應。 在運行併發垃圾回收線程的大多數時間,託管線程能夠在回收期間繼續運行。 這意味着併發GC暫停時間很是少。
所以開啓併發的垃圾回收會盡量少的執行垃圾回收,執行時間也很是短。在剩餘的時間中若是須要託管線程能夠運行和分配內存。開啓併發時咱們會在開始時給0代一個很大的分配預算來保證垃圾回收運行期間有足夠的空間分配對象。(GC中的每一代都有一個「分配預算」的概念。每一代的「分配預算」在運行時是動態調整的。由於咱們常常在0代上作分配,你能夠想象0代預算超支了,這樣就會觸發垃圾回收。這裏的預算和GC堆的段大小徹底不是一回事,預算比段大小要小得多。)
儘管如此,若是在併發回收運行中託管線程須要分配過多的內存,線程也會被堵塞直到回收完成。(在併發垃圾回收期間在堆上爲小對象分配空間的能力受到在併發垃圾回收啓動時臨時段上保留的對象的限制。 一旦到達臨時段的末尾,將必須等待併發垃圾回收完成,同時將掛起須要執行小對象分配的託管線程。)
在併發垃圾回收中,容許託管的線程在回收期間運行,記住0代和1代回收很是快,因此此選項隻影響2代回收,不影響0代和1代,即在作0,1代回收時是不會作併發回收的。只是在2代回收時纔會併發回收。
併發垃圾回收具備一個稍微大點的工做集(與非併發垃圾回收相比),這是由於你能夠在併發回收期間分配對象。 可是,這會影響性能,緣由是分配的對象將會成爲你的工做集的一部分。 實質上,併發垃圾回收會犧牲一些 CPU 和內存來換取更短的暫停。
後臺工做站垃圾回收
後臺垃圾回收只在 .NET Framework 4 及更高版本中可用。 在 .NET Framework 4 中,僅支持工做站垃圾回收。 從 .NET Framework 4.5 開始,後臺垃圾回收可用於工做站和服務器垃圾回收。
圖:對工做站上的獨立專用線程執行的後臺垃圾回收
後臺垃圾回收期間對暫時代的回收稱爲前臺垃圾回收。 發生前臺垃圾回收時,全部託管線程都將被掛起。當後臺垃圾回收正在進行而且你已在第 0 代中分配了足夠的對象時,CLR 將執行第 0 代或第 1 代前臺垃圾回收。 專用的後臺垃圾回收線程將在常見的安全點上進行檢查以肯定是否存在對前臺垃圾回收的請求。 若是存在,則後臺回收將掛起自身以便前臺垃圾回收能夠發生。 在前臺垃圾回收完成以後,專用的後臺垃圾回收線程和用戶線程將繼續。
在後臺垃圾回收中,在進行第 2 代回收的過程當中,將會根據須要收集暫時代(第 0 代和第 1 代)。
後臺垃圾回收沒法設置;它會自動運行並啓用併發垃圾回收。 後臺垃圾回收是對併發垃圾回收的替代。 與併發垃圾回收同樣,後臺垃圾回收是在一個專用線程上執行的而且只適用於第 2 代回收。
後臺垃圾回收能夠消除併發垃圾回收所帶來的分配限制,由於在後臺垃圾回收期間,可發生暫時垃圾回收。 這意味着,後臺垃圾回收能夠移除暫時代中的死對象,並且還能夠在第 1 代垃圾回收期間根據須要展開堆。
後臺服務器垃圾回收
服務器垃圾回收,這種模式和工做站模式徹底不一樣。咱們會爲每個CPU建立一個回收線程。垃圾回收在這些線程上執行而不是在分配線程上,其工做流程以下:
1. 一個託管線程作回收
2. 分配達到閥值
3. 給GC線程發信號,讓GC線程作垃圾回收,等待回收結束
4. GC線程運行,結束時發出回收完成的信號(在回收過程當中,全部的託管線程會像工做站模式中同樣被掛起)
5. 託管線程收到信號從新開始運行
從 .NET Framework 4.5 開始,後臺服務器垃圾回收是服務器垃圾回收的默認模式。 若要選擇此模式,請在運行時配置架構中將 <gcServer> 元素的 enabled 特性設置爲true。 此模式與後臺工做站垃圾回收具備相似功能,但有一些不一樣之處。 後臺工做區域垃圾回收使用一個專用的後臺垃圾回收線程,然後臺服務器垃圾回收使用多個線程,一般一個專用的線程用於一臺邏輯處理器。 不一樣於工做站後臺垃圾回收線程,這些線程不會超時。
圖:對服務器上的獨立專用線程執行的後臺垃圾回收。
要關閉併發回收,在配置文件中添加下面配置項:
<configuration>
<runtime>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>
要使用服務器GC,使用下面配置:
<configuration>
<runtime>
<gcServer enabled=「true"/>
</runtime>
</configuration>
1)若是你在寫一個獨立的託管程序而且沒有作任何配置,默認狀況下CLR 將運行工做站垃圾回收並啓用併發垃圾回收。 對於單處理器計算機和多處理器計算機都是如此。這會下降性能
2)若是應用程序是單線程而且涉及大量的用戶交互,請開啓併發垃圾回收,即不須要在配置文件中修改回收方式,便於應用程序不會由於執行垃圾回收而暫停
3)若是你的程序在宿主程序中運行,宿主可能會爲程序選擇GC的工做模式。
4)若是運行應用程序的數百個實例,請考慮使用工做站垃圾回收並禁用併發垃圾回收。 這能夠減小上下文切換,從而提升性能。
5)併發回收是爲了給用戶更好的交互體驗,適合客戶端應用程序,可是同時要注意併發回收對性能有損害,使用更多地內存。
6)若要在運行多個進程時提升性能,請禁用併發垃圾回收。
7)在工做站或服務器垃圾回收中,你能夠啓用併發垃圾回收,以便在大多數回收期間,讓各線程與執行垃圾回收的專用線程併發運行。 此選項隻影響第 2 代中的垃圾回收;第 0 代和第 1 代中的垃圾回收始終是非併發的,由於它們完成的速度很是快。
1)http://q.cnblogs.com/q/45625/
2)http://msdn.microsoft.com/zh-cn/library/at1stbec.aspx
3)http://www.cnblogs.com/yukaizhao/archive/2011/11/29/use-gc-effective-2.html
4)http://technet.microsoft.com/zh-CN/library/ee851764
5)http://blog.csdn.net/directionofear/article/details/8034133
6)http://msdn.microsoft.com/zh-cn/library/ee787088(v=vs.110).aspx