日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

減少.NET應(yīng)用程序內(nèi)存占用的一則實(shí)踐_.Net教程

編輯Tag賺U幣
教程Tag:暫無(wú)Tag,歡迎添加,賺取U幣!

推薦:進(jìn)程性能計(jì)數(shù)器已禁用的解決辦法
未處理的異常:進(jìn)程性能計(jì)數(shù)器已禁用 調(diào)試出錯(cuò): 未處理的異常: System.InvalidOperationException: 進(jìn)程性能計(jì)數(shù)器已禁用,因此無(wú)法執(zhí)行所請(qǐng)求的操作 問(wèn)題解決: 方法一: 這時(shí)只要修復(fù)一下windows的性能計(jì)數(shù)器即可。 具體方法:在運(yùn)行中輸入:lodctr /r 然后回車(chē),運(yùn)

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

減少.NET應(yīng)用程序內(nèi)存占用的一則實(shí)踐 模板無(wú)憂(yōu)

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

  一、避免創(chuàng)建不必要的對(duì)象

  拿到代碼后,第一步就是看設(shè)計(jì)文檔,然后斷點(diǎn)一步一步的看代碼,大概明白了邏輯之后,發(fā)現(xiàn)思路有一些問(wèn)題。之前的代碼處理流程思路大概是下面這樣的:

  1.將文件讀取到內(nèi)存,實(shí)例化

  2.根據(jù)條件對(duì)文件進(jìn)行檢索,并存儲(chǔ)到結(jié)果集1中

  3.對(duì)結(jié)果集1中的結(jié)果進(jìn)行匹配度計(jì)算,并存儲(chǔ)到結(jié)果集中2

  4.按對(duì)結(jié)果集2進(jìn)行匹配度排序,取最匹配的10條記錄,然后返回

  這個(gè)過(guò)程中規(guī)中矩。但是其中有很多問(wèn)題,最大的問(wèn)題是,臨時(shí)變量存儲(chǔ)了太多的中間處理結(jié)果,而這些對(duì)象在一次查詢(xún)完成后又馬上丟棄,大量的臨時(shí)對(duì)象帶來(lái)了很大的GC壓力。舉例來(lái)說(shuō),當(dāng)用戶(hù)在輸入框中輸入1的時(shí)候,假設(shè)使用Contains來(lái)匹配,那么從6萬(wàn)條記錄中找出包含1的記錄可能有4萬(wàn)多條,然后需要把這4萬(wàn)多條記錄存儲(chǔ)在臨時(shí)變量中進(jìn)行處理,進(jìn)一步計(jì)算這4萬(wàn)條記錄的匹配度,然后存儲(chǔ)到一個(gè)類(lèi)似KeyValuePair的集合中,key為匹配度,然后對(duì)這個(gè)集合按Key進(jìn)行排序,然后取前10條最優(yōu)記錄。可以看到,中間創(chuàng)建了大量的臨時(shí)變量,使得內(nèi)存劇增,大量臨時(shí)對(duì)象創(chuàng)建之后馬上會(huì)被回收,GC壓力山大。

  而在設(shè)計(jì)文檔中,只要求返回最最匹配的10條記錄,之前的解決方案中似乎并沒(méi)有注意到這一點(diǎn)。所以接手后,第一步就是對(duì)上面的處理過(guò)程進(jìn)行精簡(jiǎn)。精簡(jiǎn)后如下:

  將文件讀取到內(nèi)存,實(shí)例化

  根據(jù)條件對(duì)文件進(jìn)行檢索,如果存在,則:

  計(jì)算匹配度。

  以匹配度為Key,存儲(chǔ)到只有11個(gè)容量的SortList中。

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

  遍歷完成之后,返回這個(gè)集合對(duì)象

  經(jīng)過(guò)這一修改,減少了大量臨時(shí)數(shù)據(jù)對(duì)內(nèi)存的占用,整個(gè)過(guò)程中,我只是使用一個(gè)容量為11的SortList結(jié)構(gòu)存儲(chǔ)中間的過(guò)程,每一次插入一個(gè)元素,SortList幫我們排好序,然后移除最不匹配的那一個(gè),也就是最后一個(gè)元素(從小到大排序,越匹配,值越小)。這里面的消耗主要是 SortList的插入,內(nèi)部排序和移除記錄。 說(shuō)到這里在選擇SortList還是SortDictionary的問(wèn)題上糾結(jié)了一下,于是又找了些資料,SortDictionary在內(nèi)部使用紅黑樹(shù)實(shí)現(xiàn),SortList采用有序數(shù)組實(shí)現(xiàn), 在內(nèi)部排序都為O(logn)的前提下,SortDictionary的O(logn)插入及刪除元素的時(shí)間復(fù)雜度優(yōu)于SortList,但是 SortDictionary會(huì)比SortList占用更多內(nèi)存。基本來(lái)說(shuō)這是一個(gè)查詢(xún)速度和內(nèi)存分配之間的平衡,由于這里只需要存儲(chǔ)11個(gè)對(duì)象,所以?xún)烧呦嗖畈淮�。其�?shí)即使沒(méi)有這種結(jié)構(gòu),自己也可以實(shí)現(xiàn)的,無(wú)非就是一個(gè)集合,每次添加一個(gè),排好序,然后將最大的那個(gè)移除。.NET使用起來(lái)方便是因?yàn)橛泻芏噙@些強(qiáng)大的內(nèi)置數(shù)據(jù)結(jié)構(gòu)。

減少.NET應(yīng)用程序內(nèi)存占用的一則實(shí)踐

  經(jīng)過(guò)上面這個(gè)小小的修改,內(nèi)存占用一下子降低了1倍,從原來(lái)的70-80M,降低到了30-40M,其實(shí)這就是降低內(nèi)存開(kāi)銷(xiāo)的一個(gè)最基本的原則,那就是避免創(chuàng)建不必要的對(duì)象。

  二、優(yōu)化數(shù)據(jù)類(lèi)型及算法

  越到后面內(nèi)存的降低越來(lái)越困難。仔細(xì)看了代碼之后,除了上面之外,代碼中也有一些其他問(wèn)題,比如,一開(kāi)始就將大量的對(duì)象實(shí)例化到內(nèi)存中,然后一直保存。每一條記錄中的信息比較多,但真正有用的用于搜索匹配的只有下面四個(gè)字段,但是整體的實(shí)例化會(huì)將其他沒(méi)有用的字段也一并序列化進(jìn)去了。導(dǎo)致很多內(nèi)存被無(wú)用的字段占用。

  “股票代碼 股票中文名 中文拼音 市場(chǎng)類(lèi)型 ……

  600000 浦發(fā)銀行 PFYH 上證A股 ……”

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

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

  為此,引入了不完全搜索,就是事先對(duì)各類(lèi)型證券,如 股票,基金,債券分類(lèi),對(duì)每一類(lèi)按證券代碼進(jìn)行排序。當(dāng)用戶(hù)設(shè)置了搜索的優(yōu)先級(jí)時(shí),依次在每一類(lèi)中查找,如果找到滿(mǎn)足條件的10條記錄,則立即返回,因?yàn)閿?shù)據(jù)已經(jīng)事先按照證券類(lèi)型和代碼排好序了,所以后面找到的肯定沒(méi)有之前找到的匹配度高,這一改進(jìn)直接提高了搜索查詢(xún)的效率。對(duì)有序的數(shù)據(jù)進(jìn)行查找效率一般會(huì)比無(wú)序的數(shù)據(jù)查找效率高。我們常見(jiàn)的一些查找算法,比如說(shuō),二分查找法,前提也是待查找的集合有序排列。

  三、采用非托管代碼或者模塊編寫(xiě)數(shù)據(jù)處理邏輯

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

減少.NET應(yīng)用程序內(nèi)存占用的一則實(shí)踐

分享:ASP.NET獲取MS SQL Server安裝實(shí)例
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頁(yè)上一頁(yè)12下一頁(yè)
來(lái)源:模板無(wú)憂(yōu)//所屬分類(lèi):.Net教程/更新時(shí)間:2013-04-17
相關(guān).Net教程