狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#.NET4.0使用超大Dictionary內(nèi)存不足問題

admin
2021年3月5日 11:45 本文熱度 4023
最近需要實現(xiàn)將 XML 文件中存儲的數(shù)據(jù)統(tǒng)一讀取入內(nèi)存,并快速查詢指定數(shù)據(jù)的功能。當(dāng) XML 中的數(shù)據(jù)量不大時,這個功能非常簡單,選擇 Dictionary 數(shù)據(jù)結(jié)構(gòu),按鍵值對的方式存儲數(shù)據(jù)就好了,查詢也十分便捷。然而,我處理的 XML 數(shù)據(jù)小則幾百萬條,大則幾千萬條,使用傳統(tǒng)的方式在 .NET4.0 下會報 “System.OutOfMemory” 的錯誤。這主要是因為 .NET4.0 下有個硬性限制,單個對象不能超過 2G 。而在 .NET4.5 之后,則可以通過配置程序的 *.exe.config 文件開啟超大對象支持,來解決這個問題。當(dāng)然,必須保證你是 X64 的程序,并且物理內(nèi)存足夠。由于我的程序由于一些第三方開發(fā)庫限制,必須是基于 .NET4.0 ,雖然物理內(nèi)存足夠,這種方法并不適用。

研究了一下,最后我的解決方案還蠻 Tricky 的,分享給大家。

使用固定長度的Dictionary
可變長度的 Dictionary 在后臺實現(xiàn)時,超過某個長度就會自動擴(kuò)展容量。當(dāng)數(shù)據(jù)量很大的時候,這個擴(kuò)容的過程非常耗費(fèi)時間和內(nèi)存,有時候甚至它會占用兩倍于當(dāng)前數(shù)據(jù)大小的內(nèi)存。為了避免這種問題,應(yīng)該使用定長的 Dictionary ,防止它增長。在我的程序中,最大可以將這個長度設(shè)置為 4000000 。讀者可以按需調(diào)整。

// 示例:
Dictionary<long, string> dic = new Dictionary<long, string>(4000000);
創(chuàng)建Dictionary列表對象
既然單個對象不能超過 2G ,那么可以使用多個對象拆分存儲不就好了。于是,我試著創(chuàng)建了幾個 Dictionary 對象,當(dāng)前一個 Dictionary 對象的長度超過固定值時,我就將后面的數(shù)據(jù)存儲在下一個 Dictionary 對象中。經(jīng)過測試,這種方法是可行的。之所以說這個解決方案蠻 Tricky ,就是這個原因。

這里又引申出幾個問題,拆分成多少個 Dictionary 對象合適?每個查詢數(shù)據(jù)的地方都需要寫循環(huán)查詢每個 Dictionary 的代碼,比較冗余。于是,我將這種方法封裝成了一個單獨(dú)的類,重寫了添加、查詢的方法。我沒有寫刪除的方法,因為我不需要刪除,有需求的讀者可以自己寫,比較簡單。

類代碼如下,可參考。

public class NodeDicList
{
    private int capacity; // 每個Dictionary的固定容量
    public List<Dictionary<long, string>> dicList;
    
    public NodeDicList(int cap = 4000000)
    {
        capacity = cap;
        Dictionary<long, string> dic = new Dictionary<long, string>(cap);
        dicList = new List<Dictionary<long, string>>();
        dicList.Add(dic);
    }

// 統(tǒng)計列表總長度
    public int count()
    {
        int count = 0;
        foreach (Dictionary<long, string> dic in dicList)
        {
            count += dic.Count;
        }
        return count;
    }

// 添加新數(shù)據(jù),會自動創(chuàng)建新的Dictionary對象
    public void addItem(long key, string p)
    {
        if (dicList.ElementAt(dicList.Count - 1).Count < capacity)
        {
            dicList.ElementAt(dicList.Count - 1).Add(key, p);
        }
        else
        {
            Dictionary<long, string> dic = new Dictionary<long, string>(capacity);
            dicList.Add(dic);
            dic.Add(key, p);
        }
    }

// 查詢是否包含某個數(shù)據(jù)
    public bool containsKeyItem(long key)
    {
        foreach (Dictionary<long, string> dic in dicList)
        {
            if (dic.ContainsKey(key))
            {
                return true;
            }
        }
        return false;
    }

// 獲取某個數(shù)據(jù)的值
    public string getItemByKey(long key)
    {
        foreach (Dictionary<long, string> dic in dicList)
        {
            if (dic.ContainsKey(key))
            {
                return dic[key];
            }
        }
        return null;
    }
}
最后,如果你的對象不是 Dictionary ,是 Array 、List 等等,應(yīng)該都可以借鑒這個思路。

該文章在 2021/3/5 11:45:14 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊、財務(wù)費(fèi)用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved