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

DLL要如何釋放掉?

尚未結案
小蟲
一般會員


發表:23
回覆:35
積分:11
註冊:2004-08-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-06-01 23:11:03 IP:60.248.xxx.xxx 未訂閱
大大好~ 我寫一個DLL裡面包一個FORM 在另外寫一支呼叫DLL的程式只有一個按鈕 當我開啟呼叫DLL程式 就耗了記憶體8M 當我開啟DLL執行時 他就變成25M 我把DLL程式關掉時他不是變成8M而是變成14M 我在關掉DLL時有把他呼叫的FORM殺掉 但是我不知道該如何殺掉DLL 可否告之一下 謝謝 我有看文章想說用動態產生DLL 但是他都出現 Build [Linker Error] Unresolved external 'ShowFormReport' referenced from C:\DLL測試\UNIT2.OBJ 這種錯誤!! 就不會跑嚕 所以就不知該如何做動態產生DLL
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-06-02 01:35:44 IP:218.19.xxx.xxx 未訂閱
小蟲 您好:    Windows 系統的記憶體管理功能是很爛的,您不能對它抱著太大的期望,視窗程式佔用記憶體的狀態幾乎隨時都在變化,甚至您沒有去動它也一樣,當您執行了數支佔用記憶體很大的程式一段時間之後,再將那些程式全部都關閉掉,我向您保證執行前與結束後的可用記憶體一定不一樣,而且一定是變得比較少了,就是因為視窗系統的記憶體管理功能很差,所以才會有一大堆的 "記憶體釋放" 程式存在。 如果這個答覆不能令您信服,或是差距實在大得離譜的話,您不妨將相關的程式碼貼上來,讓有興趣的人幫忙看一下是否程式流程或設定上有問題?
小蟲
一般會員


發表:23
回覆:35
積分:11
註冊:2004-08-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-06-02 09:01:30 IP:60.248.xxx.xxx 未訂閱
我同意大大的說法 因為就妳所說的~他一開真的很大~到後來是變小了一點 只是我在想後來記憶體耗比較多是不是因為DLL沒釋放掉 所以才想問問看~ 因為我不知該如何把他釋放掉 可否告訴我~ 謝謝
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-06-02 10:35:02 IP:219.137.xxx.xxx 未訂閱
小蟲 您好:    您該不是要這個資訊吧? HINSTANCE hDllInst; // 載入 .dll 檔案 hDllInst = LoadLibrary("mylib.dll"); // 釋放 .dll 檔案 FreeLibrary(hDllInst); 幫您找了幾篇討論與轉貼文章,或許您也可以參考一下: 如何動態建立一個上窗 http://delphi.ktop.com.tw/topic.php?topic_id=32684 BCB编写DLL终极手册 http://delphi.ktop.com.tw/topic.php?topic_id=48346 BCB6使用Delphi編譯的dll產生錯誤? http://delphi.ktop.com.tw/topic.php?topic_id=47413 DLL的問題 http://delphi.ktop.com.tw/topic.php?topic_id=42637 發表人 - RedSnow 於 2005/06/02 10:36:47
小蟲
一般會員


發表:23
回覆:35
積分:11
註冊:2004-08-26

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-06-02 11:58:05 IP:60.248.xxx.xxx 未訂閱
大大妳好!! 剛剛在試做妳說的那幾種方式 所以比較慢回妳 很奇怪我有照文章上的去設~ 但是他都跟我說找不到位址 一直跑不過 我本來想用之前寫的!!但是裡面有用到報表元件 我怕大大開起會有問題 所以我另外做了一個小的 他開始跑時事7m按下按鈕他會呼叫DLL就增加500k 但是當我關掉他卻沒有減掉500k 可以幫幫忙媽 謝謝 http://myweb.hinet.net/home8/adan1234/testDLL.rar
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-06-02 12:10:53 IP:219.137.xxx.xxx 未訂閱
小蟲 您好: 透過 Proxy 下載成功了,我現在就試試看,可能要花點時間....。 發表人 - RedSnow 於 2005/06/02 12:14:10
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-06-02 12:36:31 IP:200.226.xxx.xxx 未訂閱
我還沒有開始看程式內容,我先測試您已經編譯好的 .exe 與 .dll,結果是: 1. 啟動 TESTDLL.exe 後佔用記憶體約 4.2MB (後來又漸漸往上飄,變成 4.7MB) 2. 點選按鈕呼叫出另一個子視窗,約多佔用 460KB。 3. 關閉子視窗後,吐回 12KB。 不過來回數次進行前述的 2, 3 動作後大致上會是在多佔用 16KB 與釋放回 16KB 左右的記憶體,最後在關掉子視窗後佔用的記憶體,大概比剛啟動時多佔用 500KB 左右。 我的作業環境是 Windows 2000 中文版 SP4,不知道這與記憶體佔用的不同,到底差在那裡? 我使用的是 BCB4,無法直接載入您的專案檔,我另外再看看您的程式內容好了。
小蟲
一般會員


發表:23
回覆:35
積分:11
註冊:2004-08-26

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-06-02 13:48:52 IP:60.248.xxx.xxx 未訂閱
謝謝大大的用心~ 其實我就是在想我剛開始啟動時 還沒呼叫DLL他只有4M多 但是當我呼叫DLL在關掉 他沒有變成4M多 而是6M多我可以讓他關掉時就變成一開始的狀態嗎?
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-06-02 14:48:29 IP:200.226.xxx.xxx 未訂閱
小蟲 您好:    我無法載入您的專案檔,當我自己建立專案檔時,又發現無法載入您的 Unit2.dfm 檔,後來發現該檔裡邊有設定許多的元件,因此我就另外再建立相關檔案,然後將您的相關設定複製到對應的檔案內使用,我將專案編譯後,測試的結果是: 1. 程式啟動後,記憶體的佔用會漸漸的增多。 2. 當佔用記憶體的狀態穩定後,開啟子視窗與關閉子視窗的前後比較,記憶體的消長在 8KB 左右。 3. 將整個程式結束前,佔用的記憶體約比剛啟動時多佔用 100 多 KB。 您的程式在啟動時與結束前的記憶體佔用差了 500KB,而我的程式僅差 100KB,我想這是因為您的 Unit2.dfm 佔用較多資源的關係。 後來我將 DLL 專案裡的函式宣告的 __fastcall 改成 __stdcall,重新編譯後的測試結果,與上述的狀況差不多。 我剛才想要驗證一個想法,因此又做了一次測試,這次我啟動主程式後,先不去點選按鈕開啟子視窗,而去隨意的做些與測試程式無關的操作,結果測試程式的記憶體佔用量一樣逐漸的上升 120KB,之後我再開始反覆開啟與關閉子視窗,記憶體的消長仍是 8KB,因此我猜想啟動時結束前,程式佔用記憶體的差異仍是視窗系統的問題。 補充說明: 我第二次以後的測試有修改 DLL 專案內的敘述,變動如下: 上述 __fastcall 改成 __stdcall 的地方有兩處,一是 Unit1.cpp 裡的宣告,另一處是 TEST.cpp 裡的宣告。 另外在 Unit1.cpp 裡還做了下列處理: 刪除 Form2->Free(); 改成 delete Form2; Form2 = NULL; 發表人 - RedSnow 於 2005/06/02 16:28:28
小蟲
一般會員


發表:23
回覆:35
積分:11
註冊:2004-08-26

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-06-02 16:35:24 IP:60.248.xxx.xxx 未訂閱
謝謝大大的幫忙 我大概知道你說的原因了!! 不過我跟你說一個更好玩的喔 妳要是把程式都叫起來 DLL也呼叫起來~在關掉 到TESTDLL畫面時!!妳把他最小化 記憶體會變成500k 過兩秒再還原 妳會發現他的記憶體本來是進10M 會變成3M變的很小 真怪~搞不懂︿︿
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-06-02 17:22:31 IP:200.226.xxx.xxx 未訂閱
我剛才又做了一些測試,我在 DLL 檔案內使用到的 Form 上面隨意添加了一些元件,目的在讓 DLL 被呼叫使用時佔用的記憶體大一些,以便觀察記憶體的變化。    另外我也做了另一支測試用的主程式,這支程式改用動態的方式來載入 DLL 及呼叫其內的函式,程式內在呼叫函式之前才載入 DLL,呼叫完畢後立即釋放掉,測試後的比較結果是: 1. 原先的靜態載入方式: A. 整體佔用記憶體較大 (本例為 5788KB)。 B. 呼叫 DLL 的函式後,佔用記憶體增加量較小 (本例為 1412KB)。 C. 連續呼叫多次後,沒有發現漸次增加佔用記憶體的現象。 2. 動態載入方式: A. 整體佔用記憶體較小 (本例為 4300KB)。 B. 呼叫 DLL 的函式後,佔用記憶體增加量較大 (本例為 2856KB)。 C. 連續呼叫多次後 (平均每三次),會漸次增加佔用的記憶體,每次約增加 4KB。 3. 兩種方式基本上都能在結束 DLL 的呼叫後,將記憶體釋回 (釋回成呼叫前的記憶體佔用狀態)。 4. 無論是否有執行到呼叫 DLL 函式的動作,主程式都不會在啟動後p/red]就一直保持著相同的記憶體佔用量 測試方式為直接呼叫出 DLL 的子視窗,然後再[red]直接關閉掉 DLL 的子視窗,沒有做其它操作,若是 DLL 的子視窗中有其它的動作,記憶體佔用與釋回的狀況可能會有所不同。 連續動態載入與釋放 DLL 佔用空間時,會漸次多耗損約 4KB 記憶體的現象,查看站上資料後,我個人認為下列這篇討論中 Albertz 的說明可能是正解,也就是說應該是 Data Segment 留下的垃圾: DLL的問題 http://delphi.ktop.com.tw/topic.php?topic_id=56074 以上測試結果與相關資訊供 小蟲 及其他瀏覽本文的網友們參考。
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-06-02 17:53:51 IP:200.226.xxx.xxx 未訂閱
小蟲 您好:
引言:不過我跟你說一個更好玩的喔 妳要是把程式都叫起來 DLL也呼叫起來~在關掉 到TESTDLL畫面時!!妳把他最小化 記憶體會變成500k 過兩秒再還原 妳會發現他的記憶體本來是進10M 會變成3M變的很小 真怪~搞不懂︿︿
這個現象也是 Windows 搞的鬼,視窗系統的記憶體管理功能不佳,而視窗系統本身是全圖形的作業環境,吃記憶體非常的兇,因此它搞出個虛擬記憶體來做輔助,當主記憶體不敷使用時,視窗系統就會設法將一些可以暫時用不著的資料切換到虛擬記憶體去,然後釋放一些主記憶體出來供其它程式使用,如果您的記憶體並不大,那麼視窗系統是拿磁碟空間來當作虛擬記憶體,當您碰上記憶體不足時,您就會發現您的磁碟 I/O 會非常的頻繁。 當您將程式作最小化處理時,因為省卻了畫面的佔用,視窗系統發現後,就趕緊將儲存畫面資料的記憶體空間切換到虛擬記憶體去 (系統可能也會假設最小化的程式會暫時用不著程式內所配置使用的其它資料空間,因而將那些空間也一併轉存到虛擬記憶體去),然後釋放部份記憶體出來,因此您就會發現記憶體變多了,但是當您再將程式切換回正常顯示狀態後,視窗系統又會將存放在虛擬記憶體裡的畫面資料抓回主記憶體來顯示,因此程式佔用的記憶體就會又變多了,雖然不是一次就恢復成原先的佔用量,但是簡單的操作一下後,就會漸漸的被打回原形了,所以您看到的情形是個假象、是個偷吃步的伎倆。 當您將系統中所有執行中的程式全部關閉後,您絕對不可能看到剩餘的可用記憶體會與剛開機時一樣。 總結: 說好聽點 - 視窗系統顧及了實體記憶體較小的用戶,讓大家都有機會去使用那些猛吃記憶體的龐然巨獸。 說難聽點 - 視窗系統只知如何吞光記憶體卻不知如何乾乾淨淨的全部吐出來,這樣的記憶體管理真的爛!
系統時間:2024-05-03 23:30:37
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!