中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何查找.NET程序內存不斷上漲的原因

發布時間:2021-10-29 16:45:13 來源:億速云 閱讀:148 作者:柒染 欄目:編程語言

如何查找.NET程序內存不斷上漲的原因,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

前段時間公司新寫的自動升級服務端(Remoting)出現了內存不斷飆升的情況,從最初的七八十兆一晚上竟然飆到了1G多,直接導致客戶端連接服務端失敗,這不科學,后來優化了各種可能造成占用內存的方法(數據庫連接,I/O操作,引用類型釋放),但效果不佳,這下可難為我們了,不知道問題的所在也就不知道該如何去修改。

我們知道.NET是帶有垃圾回收機制的,出現這種情況一般是由某些數據長期存活在內存中又不能被當成垃圾數據回收的原因造成的。

后來就在各搜索引擎上進行了各種搜索,有說使用windebug分析dump,但需要大量時間琢磨,有人說是不是硬件問題,還有人說中毒了,***找到了一款微軟推出的CLRProfiler工具,貌似很強大,遂MSDN了一把,MSDN是這樣說的:

Who allocates what on the managed heap.

Which objects survive on the managed heap.

Who is holding on to objects.

What the garbage collector does over the lifetime of your application.

得到這些信息以后就決定使用一下,讓服務端運行了一會兒,停止以后得到分析結果,最終在Allocation Graph視圖下了解到原來是下載文件DownloadFile方法下的byte[]數組引起的,短短不到一分鐘的時間竟然占用了兩百多兆的內存,好了,這下可找到“原兇”了,有得折騰了

方案1:把要下載的數據一并加載到內存,用戶在下載的時候通過position來獲取byte[]不新建直接返回,是能解決問題,但這就大大降低了服務端的可用性啊,只能當做小文件服務端,太不合理。

方案2:由于下載文件的時候返回的是一個可序列化的類,所以想是不是這里出現了問題,可以直接返回byte[],以最基本的數據頭->數據長度->數據->數據尾來實現,但這樣一來要改的東西太多了,服務端客戶端,協議重構,眼看著就要落幕的項目卻要重頭再來心有不甘那,再加上還有一堆任務在后面趕著,這不是坑自己嗎,也放棄了。

然后又回到各種網絡資料搜索上,經過一番查找后了解到,byte[]最終也是會被回收的,只要是托管的數據都是能被回收的,只是周期可能會長一些,***又回到了Remoting本身上,抱著試一試的心態把WellKnowObjectMode由SingleTon改為了SingleCall,跑了一晚上***穩定在了200M上下,總算松了口氣。

使用SingleTon本來是想節省內存消耗的,可沒想到得不償失如此的大費周折,遂總結出SingleTon并不適合并發量大的服務端程序,SingleTon是單線程模式,在調用每個方法的時候都會被加鎖,猜測造成數據一直不能被釋放的原因是由這些鎖造成的,由于連接的數量太多導致連接一直處于排隊狀態,造成了后面連接的客戶端響應過慢,連接超時,在這里也給大家一個教訓還是用SingleCall實在。

上面說了這么多只是跟大家分享一下解決問題的經驗,還有敘述了一下問題的所在,如果各位有不同的見解請一定要指出來,畢竟.NET內存分配、垃圾回收本就比較復雜。

然事與愿違卻柳暗花明

這篇文章的重點是講如何使用CLRProfiler來查找.NET程序的內存分配情況的,下面就開始吧。

下載CLR Profiler:http://search.microsoft.com/en-us/DownloadResults.aspx?q=clr%20profiler

可根據自己.NET的版本下載相應的CLRProfiler,下面以.NET4.0版本為例。CLRProfiler可以分析應用程序,服務和ASP.NET編寫的程序,以下以應用程序為例為大家演示如何簡單使用CLRProfiler。

下面是一個拆箱裝箱的例子CLRProfilerTestDemo,通過這個例子來觀察進程托管堆的分配和研究垃圾回收機制的行為表現,代碼如下

using System;  using System.Collections.Generic;  namespace CLRProfilerTestDemo  {      class Program      {          static void Main(string[] args)          {              for (int i = 0; i < 100 * 1000; i++)              {                  Boxing box = new Boxing();              }               Environment.Exit(Environment.ExitCode);          }      }       class Boxing      {          private List<object> box = new List<object>();          private List<int> unbox = new List<int>();           public Boxing()          {              for (int i = 0; i < 1000; i++)              {                  box.Add(i);                  unbox.Add((int)box[i]);              }          }      }  }

運行CLRProfiler,選中Allocation和Calls選項如下圖:

如何查找.NET程序內存不斷上漲的原因

編譯程序,點擊Start Application選擇CLRProfilerTestDemo.exe,將會運行此程序,運行一段時間后,點擊Kill Application,CLRProfiler將會顯示分析結果。

如何查找.NET程序內存不斷上漲的原因

打開Allocated bytes直方圖界面,如下圖,在右側的分配類型區可以找到可疑的類Boxing

如何查找.NET程序內存不斷上漲的原因

下面是Allocation Graph內存分配視圖,在這個視圖當中我們可以看出堆棧是如何分別對象的。

如何查找.NET程序內存不斷上漲的原因

通過CLRProfiler工具進行這幾步簡單的操作即可找出造成應用程序內存飆升的源頭,并想辦法修復。

關于如何查找.NET程序內存不斷上漲的原因問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

霍州市| 抚顺县| 云和县| 都江堰市| 乐昌市| 兴义市| 大田县| 资溪县| 卢湾区| 庆云县| 延寿县| 营口市| 汤阴县| 堆龙德庆县| 南宫市| 云和县| 余庆县| 庄浪县| 上犹县| 鹤壁市| 永寿县| 游戏| 洛隆县| 汽车| 沈丘县| 定边县| 凌源市| 疏勒县| 页游| 吉隆县| 彰武县| 华阴市| 尉犁县| 英吉沙县| 泾阳县| 通城县| 阿巴嘎旗| 晋宁县| 洪泽县| 田阳县| 车险|