用虛擬記憶體來訪問大檔案

2021-06-08 09:05:10 字數 1615 閱讀 3631

這段時間在論壇上看見一些人問起如何讀取很大的檔案或者資料結構,我一時也想不出什麼辦法,只有建議更換策略,不要為難記憶體。

在32位機上(64位也是一樣的,但是空間大很多),乙個程序可以分配到4gb的虛擬記憶體,當然,其中2g給了核心,剩下2gb有一些分給了**段、資料段,最後剩下的就是給我們程式設計師用的了,這樣看來,乙個應用程式若硬生生的讀取2gb左右的資料是乙個極限了。

不過事實並非如此,只要利用虛擬記憶體技術有時還是可以讀取的。

先簡單說說windows虛擬記憶體的思路:

所謂虛擬記憶體,就是事實上可能還沒有得到實際記憶體的記憶體,如果cpu要訪問乙個虛擬記憶體,哪麼作業系統得首先判斷這個虛擬記憶體有沒有獲得實際記憶體。如果有,那大可以大大方方的讀取,甚至寫資料。

但若如果沒有,作業系統就必須在實際記憶體上找到一塊地方,建立起與要讀取虛擬記憶體的對映關係,這樣就可以讀取了。當然若是找不到這麼多實際記憶體,那麼可以一些暫時還沒用到的實際記憶體放到更低一級的硬碟臨時空間上,騰出空間來,再建立與虛擬記憶體的對映關係。

當然了,比如要讀取2gb的資料,在1g記憶體上是無論如何也沒法找到足夠空間建立對映關係的。我們當然不可能一次性讀取2gb資料,所以引入「頁」這個概念,即每次虛擬記憶體射到實際記憶體上的時候,都是按頁大小對映的,這個頁大小,與cpu有關,在x86上一般是4kb。

說到這,讀取大型資料的思路就出來了,我們可以先分配虛擬記憶體,等到我們讀或者寫當中的一些資料的時候,再分配實際記憶體,由於這些都是在記憶體這一級操作,效率遠比讀寫資料的時候再從硬碟取出來的高。

windows api讓我們輕鬆做到這一點。

virtualalloc,可以申請到乙個虛擬記憶體,或者實際對映到實際記憶體的記憶體。我們可以先申請虛擬記憶體,等到真的要讀取某處資料的時候,再申請實際記憶體(建立對映關係)。

詳細可以看msdn,下面給出乙個示例**:

#include 

#include 

#include 

struct  sheet                           //我們要讀取的資料結構

;int main()

else

//申請虛擬記憶體,mem_reserve表示不會和實際記憶體建立對映關係

lpvoid lpbaseaddr = virtualalloc(null, dwoccupy * 50, mem_reserve, page_readwrite);

if (lpbaseaddr == null)

__try

else}}

//建立成功,讀/寫資料

sheet * psheet = (sheet*)lpsheetaddr;

psheet->nsize = 9;

psheet->strtext = "hello world";

psheet->bvisible = true;}}

__except(exception_execute_handler)

//釋放記憶體

virtualfree(lpbaseaddr, 0, mem_release);}

當然,這其中用到了乙個影響效率的virtualquery函式,其實可以用異常處理手段提高效率的,留待以後再說。

還可以新增刪除**,一些資料不再用到的時候,可以把虛擬記憶體狀態重新置為mem_reserve,這樣可以節省實際記憶體。

使用spring來訪問靜態資料夾下的檔案

mvc resources location static static mvc resources mvc resources location css css mvc resources mvc resources location js js mvc resources mvc resourc...

記憶體對映檔案 虛擬記憶體

windows提供了3種進行記憶體管理的方法 虛擬記憶體,最適合用來管理大型物件或結構陣列。記憶體對映檔案,最適合用來管理大型資料流 通常來自檔案 以及在單個計算機上執行的多個程序之間共享資料。記憶體堆疊,最適合用來管理大量的小物件。再通俗點,就是比如 要讀取乙個檔案裡的東西 這時候你就得去硬碟讀,...

力扣打不開,通過修改hosts檔案來訪問

最近幾天我登入老是顯示網路連線失敗 重新整理多次才偶爾能開啟,訪問別的 都沒有問題 什麼是hosts檔案?hosts是乙個沒有副檔名的系統檔案,其基本作用就是將一些常用的 網域名稱與其對應的ip位址建立乙個關聯 資料庫 當使用者在瀏覽器中輸入乙個需要登入的 時,系統會首先自動從hosts檔案中尋找對...