網站公告 :


Delphi K.Top討論區 » 難以歸類主題的討論區(C++Builder) » [心得] 要求系統釋放記憶體
發表新文章
 
主題:[心得] 要求系統釋放記憶體
瀏覽次數:7408
dllee
站務副站長




發表:315
回覆:2470
積分:1695
註冊:2002-04-15

發送簡訊給我
#1 發表時間:2002-07-29 10:21:38 IP:61.231.xxx.xxx 未訂閱

「要求系統釋放記憶體」的心得
原理是在程式中動態配置一個很大的記憶體,比現有可用的實體記憶體還大,這時系統為了滿足這個「正在執行中」的程式的要求,於是將一些已不太使用的記憶體區塊放到虛擬記憶體中。

在實際撰寫「要求系統釋放記憶體」的程式時發現,當程式向系統要一塊很大的 Buffer 時,如 char *pBuffer=new char[200*1024*1024]; 系統並不是將「實體記憶體」分配給它,而是將「虛擬記憶體」分配給它。
當程式對於 pBuffer[i] 作存取時,才發現「實體記憶體」的大小開始變小了,不過此程式所占用的「虛擬記憶體」並沒有變小喔。而當「實體記憶體」變得只剩不到 1MB 時,可以發現系統速度變慢了,這是因為系統開始整理記憶體了,把一些已不太使用的記憶體區塊釋放,此時,可以發現其他程式所占用實體記憶體的大小開始變小了,同樣地,其他程式所占用的「虛擬記憶體」並沒有變小或變大,也就是說,沒有所謂「將不用的實體記憶體放到虛擬記憶體」?是這樣嗎?

但是程式執行速度明顯變慢,而且可以看到(聽到)硬碟正在努力地存取中,有可能是將不用的實體記憶體內的資料「更新」回虛擬記憶體中。(這只是猜想)

為了加快此程式釋放記憶體的速度,於是筆者將存取 pBuffer[i] 由每 byte 都存取,改成每 1KB 只存取 1 byte、再改成每 2KB 只存取 1 byte、再改成每 4KB 只存取 1 byte、再改成每 8KB 只存取 1 byte...
當改成每 8KB 只存取 1 byte 在釋放記憶體時,發現此程式所占用的實體記憶體並沒有每 4KB 只存取 1 byte 時來得大,這也使得釋放記憶體功能失效!所以,最佳的狀態是每 4KB 只存取 1 byte,而這也有可能因系統而異。

【結論】
在釋放記憶體的過程中,其他程式所占用的虛擬記憶體並沒有增大!可以大膽的推論,程式所有必要的程式資料碼都已放在虛擬記憶體中,而在執行的過程,才將有用到的部分移到實體記憶體中執行。

而系統在使用實體記憶體時,是以 Page 為單位,一個程式在執行時有用到的程式或資料會放到可用的 Page 中,而程式所「認知」的記憶體位址,其實是系統「告知」的,所以有可能在程式中認為一個 Buffer 在執行時其記憶體是「連續」的,但這是經由系統適當配置後,讓這個程式認為它所用的 Buffer 記憶體是連續的,但真正所使用到的實體記憶體很有可能是四分五裂的區塊!
在筆者的系統中,一個 Page 的大小也許就是 4KB,這可以解釋當存取間隔是在 4KB 以下時,其占用實體記憶體的狀況相近,而當存取間隔大於 4KB 如 8KB 時,雖然在程式中也是「連續」地使用它,但它真正在實體記憶體中卻只有 8KB 中有存取到的那一個 byte 被放到一個 4KB 的 Page 中。


void __fastcall TFormMemFree::FreeMemory(int iFreeSize)
{
    this->Caption="記憶體釋放中...";
    iFreeSize=iFreeSize << 20; // 單位為 MB

// 方法1:無效
// char *pBuffer=new char[iFreeSize];
// delete [] pBuffer;

// 方法2:有效,要真的去存取資料才會真的配置?!
    char *pBuffer=new char[iFreeSize];
    int iStep=4*1024;        // 實驗結果 1K,2K,4K 可,8K 以上太大就不行
    for(int i=iStep-1;i<iFreeSize;i += iStep) // 以 K 為單位,加快存取時間
    {
    if(bAbort) break;        // 如果要求中止,則不再向系統要記憶體
    pBuffer[i]=0x0;
    iFreeingPercent=((i+1)>>10)*100/(iFreeSize>>10);
    this->Caption="記憶體釋放中..."+IntToStr(iFreeingPercent)+" %";
    Application->ProcessMessages();
    }
    delete [] pBuffer;
    this->Caption="記憶體釋完成!!";
}


以上的推論都是按實測的結果及小弟個人的推理所得,小弟必需先聲明,我沒有上過、看過任何作業系統的書及課,所以,以上的推論可能有錯,請懂原理的網友多多指教,讓小弟可以更了解記憶體管理。

------
http://blog.yam.com/dllee/


ddy
站務副站長




發表:262
回覆:2072
積分:1153
註冊:2002-07-13

發送簡訊給我
#2 發表時間:2002-07-29 12:17:40 IP:210.64.xxx.xxx 未訂閱

dllee兄果然夠精實…呵呵:p
以我的了解(與轉錄候捷的大作)

目前的電腦不可能安插 4GB 記憶體,所以作業系統使用一個磁碟置換檔
(disk swap file)暫時接受實際記憶體無法容納的資料。
因此雖然電腦只有 128MB 或 256MB,應用程式卻可能取用 4GB 虛擬記憶體。
不過,作業系統必須能夠把 page(虛擬記憶體的運作單位)搬移到實際記憶體的任何一個地點才行。(符合dllee兄的論點)
虛擬位址對應用程式而言是不變的;將它轉換為實際位址,是CPU 的責任 。

但是程式執行速度明顯變慢,而且可以看到(聽到)硬碟正在努力地存取中,有可能是將不用的實體記憶體內的資料「更新」回虛擬記憶體中。(這只是猜想)
==我覺得是將不常用的頁面(RAM中)與Virtual memory 的頁面交換 ==

---以下結錄候捷的windows 95 programming---
---所以推論"虛擬記憶體之所以沒有變小,可能是僅有狀態的改變"

分頁機制使得作業系統得以保留巨大的記憶體位址範圍,直到真正需要 RAM 為止。

任何時候,CPU 的 4GB 位址空間中,每一個 4K 區段(一頁)有四種可能的狀態:
狀態1:Available ,表示這頁記憶體並沒有保留給任何人。任何人可以經由配
置動作擁有它。企圖讀寫這塊記憶體將會導至 "page fault" 異常情況(exception
0Eh )

狀態2:Reserved ,表示這一頁已經被某人要走了。然而,RAM 還沒有被映
射到這個位址,也沒有任何硬碟空間保留用來複製其內容。企圖讀寫這塊記憶
體將會導至 "page fault" 異常情況(exception 0Eh )。作業系統給予這個區塊
的擁有者一個機會,把狀態改變為 Committed and Present 。

狀態3:Committed and present ,表示這位址已經被配置給某人,並且有一
個程式已經用它來儲存資料。CPU 的分頁機制也已經把 4K RAM 映射到此
位址。讀寫此塊位址也就是讀寫映射之實際記憶體。這個狀態還有一個子狀態
稱為 pagelocked ,表示這一頁是 committed 、present 、並保證絕不會被置換
(swapped out )出去。當 page 處於 pagelocked 狀態,永遠會有實際記憶體
映射到該 page ,直到它變成 unpagelocked 狀態。

狀態4:Committed and not-present ,這和前一狀態十分類似,程式已經配置
此塊記憶體並用它來儲存資料。不同之處在於作業系統已經決定,其他地方更迫
切需要映射至此區的RAM 。因此,CPU 已經把此區內容拷貝到硬碟之中,
並把此區的每一頁標記為 Not Present (譯註:Not Present 表示位址並沒有映
射到實際記憶體)。
和狀態1 、狀態2 一樣,如果這樣的 page 被存取,會發生 page fault 。
不同之處在於當程式存取這樣的位址,作業系統會自動處理page fault 異常情況並重新映射一塊
4MB RAM 過來。然後作業系統會讀取硬碟中的原來資料,再重新執行發生 page fault
之前的那個指令。於是程式完全不知道有 page fault 發生。這樣透明化的以硬碟模擬
RAM 正是虛擬記憶體的基礎。


噓~~~~~~沉思中…


dllee
站務副站長




發表:315
回覆:2470
積分:1695
註冊:2002-04-15

發送簡訊給我
#3 發表時間:2002-07-29 18:08:47 IP:61.231.xxx.xxx 未訂閱

所以,page 的單位就真的是 4KB 囉?!
可以修改嗎?
另外,您所說的 pagelocked 狀態,我們寫程式可以設定嗎?
我在寫這個程式時都是用 PSP(Pen Shop Pro) 在測試,用它開一個空白的大圖檔使記憶體快速用完,而在 Free 時,我發現 PSP 所占用的實體記憶體並不會因為我程式的 Free 而變小,不知是不是就是有用到 pagelocked 的技術呢?



------
http://blog.yam.com/dllee/

ddy
站務副站長




發表:262
回覆:2072
積分:1153
註冊:2002-07-13

發送簡訊給我
#4 發表時間:2002-07-29 23:51:48 IP:211.74.xxx.xxx 未訂閱

嗚~~~~~~剛剛打的都不見了><~~~

dllee兄
    以我所知,頁面大小是可以改變的
但是頁面管理是CPU與作業系統的配合
除非是要RUN不同的硬體平台,不然單單改作業系統,也不見得能正常運作
就像X86 CPU一個Page就是4k
    Alpha CPU一個Page就是8k
在Linux裡的Source code 有Page size 的變數可改,應是為了不同平台的相容吧,Windows 95/98 系列應該就是4k,NT系統就不一定吧,因為NT好像也能跑Alpha 的CPU吧…(:p~~不太確定)
Red hat Linux 7.3裡的/usr/src/linux-2.4.18-3/mm 裡有Linux記憶體管理的Source code ,我大致看過了…嗯…太深奧了^^|||
您有興趣可以安裝玩玩看,了解一下


您執行完PSP後,所佔的memory,並不是被釋放
此時它的狀態應該是由Committed and present狀態的子狀態pagelocked 改變為unpagelocked (並非主動釋出頁面對應)
然後unpagelocked狀態回復至Reserved,表示這一頁目前仍被某程式佔用。然而,RAM 目前還沒有新的內容映射到這個位址,也沒有任何硬碟空間保留用來複製其內容。若其它程式企圖讀寫這塊記憶體將會導至 "page fault" 異常情況(exception 0Eh )。作業系統給予這個區塊
的擁有者一個機會,把狀態改變為 Committed and Present 或是Committed and not-Present
不斷的發生page fault(尋頁缺失)不斷的改變狀態,直至停止發生page fault


以上是我的看法啦…:p 呵呵…愈來愈心虛了
如果觀念有誤,請高手指教


噓~~~~~~沉思中…


dllee
站務副站長




發表:315
回覆:2470
積分:1695
註冊:2002-04-15

發送簡訊給我
#5 發表時間:2002-07-30 10:28:53 IP:61.231.xxx.xxx 未訂閱

引言:

嗚~~~~~~剛剛打的都不見了><~~~


哇!您也遇到了!有時真的是很想哭吧
希望站長天使大人能有法力將小弟所建議的「將內文複製到剪貼簿」的功能變出來!
引言:

...
…嗯…太深奧了^^|||
...
以上是我的看法啦…:p 呵呵…愈來愈心虛了
如果觀念有誤,請高手指教
噓~~~~~~沉思中…


說真的,有點太深奧了,我只是想「大概」了解一下 Windows 的記憶體管理方式,而您介紹
侯捷大師的《Windows 95 系統程式設計 大奧秘》
我已到侯捷大師重新下載,有空的話,會翻翻看的,遇到有任何問題,再請教您囉。


------
http://blog.yam.com/dllee/

ddy
站務副站長




發表:262
回覆:2072
積分:1153
註冊:2002-07-13

發送簡訊給我
#6 發表時間:2002-07-30 17:15:35 IP:210.64.xxx.xxx 未訂閱

引言:
我已到侯捷大師重新下載,有空的話,會翻翻看的,遇到有任何問題,再請教您囉。


dllee兄
    別說請教啦…這樣子大家討論,也是獲益蠻多的
藉著討論,push自己,不然有時也會偷懶的啦…:p




噓~~~~~~沉思中…


系統時間:2010-09-03 19:07:57,  線上使用者 259 / Max 3,401,主題數:92,416,回覆數:208,133。  聯絡我們 | Delphi.ktop討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!

趴趴狗旅遊網大花蓮旅遊網大花蓮民宿網花蓮市旅遊網花蓮市民宿網大南投旅遊網大南投民宿網
日月潭風景區日月潭旅遊網日月潭民宿網台東旅遊網台東民宿網集集旅遊網集集民宿網
關子嶺旅遊網關子嶺民宿網白河旅遊網白河民宿網
. . . . . . . .