線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:13515
推到 Plurk!
推到 Facebook!

[心得] 要求系統釋放記憶體

 
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊: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://www.ViewMove.com
ddy
站務副站長


發表:262
回覆:2105
積分:1169
註冊: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
站務副站長


發表:321
回覆:2519
積分:1711
註冊: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://www.ViewMove.com
ddy
站務副站長


發表:262
回覆:2105
積分:1169
註冊: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
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2002-07-30 10:28:53 IP:61.231.xxx.xxx 未訂閱
引言: 嗚~~~~~~剛剛打的都不見了><~~~
哇!您也遇到了!有時真的是很想哭吧 希望站長天使大人能有法力將小弟所建議的「將內文複製到剪貼簿」的功能變出來! <>< face="Verdana, Arial, Helvetica">引言: ... …嗯…太深奧了^^||| ... 以上是我的看法啦…:p 呵呵…愈來愈心虛了 如果觀念有誤,請高手指教 噓~~~~~~沉思中… 說真的,有點太深奧了,我只是想「大概」了解一下 Windows 的記憶體管理方式,而您介紹 侯捷大師的《Windows 95 系統程式設計 大奧秘》 我已到侯捷大師重新下載,有空的話,會翻翻看的,遇到有任何問題,再請教您囉。
------
http://www.ViewMove.com
ddy
站務副站長


發表:262
回覆:2105
積分:1169
註冊:2002-07-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2002-07-30 17:15:35 IP:210.64.xxx.xxx 未訂閱
引言: 我已到侯捷大師重新下載,有空的話,會翻翻看的,遇到有任何問題,再請教您囉。
dllee兄 別說請教啦…這樣子大家討論,也是獲益蠻多的 藉著討論,push自己,不然有時也會偷懶的啦…:p 噓~~~~~~沉思中…
系統時間:2024-03-29 19:20:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!