国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

減少.NET應用程序內存占用的一則實踐_.Net教程

2024-07-10 12:52:09
字體:
來源:轉載
供稿:網友

推薦:進程性能計數器已禁用的解決辦法
未處理的異常:進程性能計數器已禁用 調試出錯: 未處理的異常: System.InvalidOperationException: 進程性能計數器已禁用,因此無法執行所請求的操作 問題解決: 方法一: 這時只要修復一下windows的性能計數器即可。 具體方法:在運行中輸入:lodctr /r 然后回車,運

  最近一周比較忙,主要的工作內容是在做一個叫“鍵盤精靈”的東西,簡單來講就是將很多數據放到內存中,對這些數據進行快速檢索,然后找出根據輸入條件最匹配的10條記錄并予以展示。具體和下面兩款炒股軟件的相關功能類似:

減少.NET應用程序內存占用的一則實踐 武林網

  數據以文本形式存在文件中,且數據量較大,有近20萬條,每一條記錄有幾個字段,以分隔符分割。當時使用的是6萬條記錄的測試數據,文本文件將近 10M,這個模塊加載到內存并建立緩存之后,大概會占用將近70-80M的內存。自我接手以后,主要的任務就是降低內存消耗和提高匹配效率。

  一、避免創建不必要的對象

  拿到代碼后,第一步就是看設計文檔,然后斷點一步一步的看代碼,大概明白了邏輯之后,發現思路有一些問題。之前的代碼處理流程思路大概是下面這樣的:

  1.將文件讀取到內存,實例化

  2.根據條件對文件進行檢索,并存儲到結果集1中

  3.對結果集1中的結果進行匹配度計算,并存儲到結果集中2

  4.按對結果集2進行匹配度排序,取最匹配的10條記錄,然后返回

  這個過程中規中矩。但是其中有很多問題,最大的問題是,臨時變量存儲了太多的中間處理結果,而這些對象在一次查詢完成后又馬上丟棄,大量的臨時對象帶來了很大的GC壓力。舉例來說,當用戶在輸入框中輸入1的時候,假設使用Contains來匹配,那么從6萬條記錄中找出包含1的記錄可能有4萬多條,然后需要把這4萬多條記錄存儲在臨時變量中進行處理,進一步計算這4萬條記錄的匹配度,然后存儲到一個類似KeyValuePair的集合中,key為匹配度,然后對這個集合按Key進行排序,然后取前10條最優記錄。可以看到,中間創建了大量的臨時變量,使得內存劇增,大量臨時對象創建之后馬上會被回收,GC壓力山大。

  而在設計文檔中,只要求返回最最匹配的10條記錄,之前的解決方案中似乎并沒有注意到這一點。所以接手后,第一步就是對上面的處理過程進行精簡。精簡后如下:

  將文件讀取到內存,實例化

  根據條件對文件進行檢索,如果存在,則:

  計算匹配度。

  以匹配度為Key,存儲到只有11個容量的SortList中。

  如果SortList集合添加記錄后大于10個,則移除最后面一個元素,始終保持著前10個最小(匹配度最優)的記錄。

  遍歷完成之后,返回這個集合對象

  經過這一修改,減少了大量臨時數據對內存的占用,整個過程中,我只是使用一個容量為11的SortList結構存儲中間的過程,每一次插入一個元素,SortList幫我們排好序,然后移除最不匹配的那一個,也就是最后一個元素(從小到大排序,越匹配,值越小)。這里面的消耗主要是 SortList的插入,內部排序和移除記錄。 說到這里在選擇SortList還是SortDictionary的問題上糾結了一下,于是又找了些資料,SortDictionary在內部使用紅黑樹實現,SortList采用有序數組實現, 在內部排序都為O(logn)的前提下,SortDictionary的O(logn)插入及刪除元素的時間復雜度優于SortList,但是 SortDictionary會比SortList占用更多內存。基本來說這是一個查詢速度和內存分配之間的平衡,由于這里只需要存儲11個對象,所以兩者相差不大。其實即使沒有這種結構,自己也可以實現的,無非就是一個集合,每次添加一個,排好序,然后將最大的那個移除。.NET使用起來方便是因為有很多這些強大的內置數據結構。

減少.NET應用程序內存占用的一則實踐

  經過上面這個小小的修改,內存占用一下子降低了1倍,從原來的70-80M,降低到了30-40M,其實這就是降低內存開銷的一個最基本的原則,那就是避免創建不必要的對象。

  二、優化數據類型及算法

  越到后面內存的降低越來越困難。仔細看了代碼之后,除了上面之外,代碼中也有一些其他問題,比如,一開始就將大量的對象實例化到內存中,然后一直保存。每一條記錄中的信息比較多,但真正有用的用于搜索匹配的只有下面四個字段,但是整體的實例化會將其他沒有用的字段也一并序列化進去了。導致很多內存被無用的字段占用。

  “股票代碼 股票中文名 中文拼音 市場類型 ……

  600000 浦發銀行 PFYH 上證A股 ……”

  所以第一步就是在內存中只存放需要檢索的上面四個關鍵字段,每一條記錄剛開始是使用string[]數據,而不是使用類或者其它結構來保存,也嘗試使用結構提來保存,但是由于四個字段,數據量大,中間還要作為參數傳遞,所以比使用類還大,這里只是簡單的使用了數組。

  除了上面這些之外,為了提高搜索效率,對數據按照0-9,a-z開頭對數據做了切分分塊緩存,這樣當用戶輸入0時,直接從以0為key的塊中讀取數據,這樣速度是加快了,但是大量的緩存也增加了對內存的消耗。緩存的數據基本上和加載到內存中原始的數據一樣大了。并且在搜索的過程中,也是采用的完全搜索,對于17萬條數據的四個字段,每一次查詢要進行170000*4次遍歷比較,才能找出最匹配的10條數據來。

  為此,引入了不完全搜索,就是事先對各類型證券,如 股票,基金,債券分類,對每一類按證券代碼進行排序。當用戶設置了搜索的優先級時,依次在每一類中查找,如果找到滿足條件的10條記錄,則立即返回,因為數據已經事先按照證券類型和代碼排好序了,所以后面找到的肯定沒有之前找到的匹配度高,這一改進直接提高了搜索查詢的效率。對有序的數據進行查找效率一般會比無序的數據查找效率高。我們常見的一些查找算法,比如說,二分查找法,前提也是待查找的集合有序排列。

  三、采用非托管代碼或者模塊編寫數據處理邏輯

  上面的兩部操作雖然減少了將近50-60%的內存占用,但是仍然達不到領導的要求,于是又嘗試并比較了各種 使用不同的數據結構將數據載入到內存中的內存占用大小,包括直接將文件按類型讀成字符串、數組、結構及類,內存占用最小的直接將文件讀成字符串,10M的數據文件讀進內存也會占用20-30M的空間,還不談對其進行處理過程中產生的一些臨時變量對內存的占用。使用dotTrace及CLR Profile等工具檢查之后,發現內存的占用也是這些原始數據。然后以” How to reduce the memory usage of .NET applications” 到網上搜了一下減少.NET內存占用的一些方法,在StackOverflow上看到了這一回答:

減少.NET應用程序內存占用的一則實踐

分享:ASP.NET獲取MS SQL Server安裝實例
View Code protected void Page_Load(object sender, EventArgs e) { DataTable dataTable = SqlDataSourceEnumerator.Instance.GetDataSources(); foreach (DataRow dr in dataTable.Rows) { if (string.IsNullOrEmpty(dr[InstanceName].ToString())) this.DropDownLi

共2頁上一頁12下一頁
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 栾城县| 罗甸县| 民丰县| 芮城县| 英德市| 奎屯市| 故城县| 隆回县| 伊金霍洛旗| 金川县| 崇左市| 沾益县| 黑水县| 长汀县| 如皋市| 额尔古纳市| 卢氏县| 裕民县| 万年县| 福泉市| 金坛市| 金阳县| 遵化市| 天门市| 乌鲁木齐县| 汉寿县| 修武县| 贞丰县| 任丘市| 连云港市| 鹤岗市| 德清县| 报价| 奇台县| 吐鲁番市| 屯门区| 营口市| 田东县| 睢宁县| 高要市| 托克逊县|