我在Windows Vista及以上版本中遇到過一個奇怪的問題。當我用大堆棧使用IFileOpenDialog時,顯示對話框後剩餘的內存量下降了大約1 GB。Windows Vista +內存IFileOpenDialog和大堆棧的問題
#include <windows.h>
#include <Shobjidl.h>
#include <iostream>
void memGrab(char *);
int main(int argc, char **argv){
char Message[128];
CoInitialize(NULL);
if(argc > 1){
wsprintf(Message, "Starting Memory Test: %c", argv[1][0]);
std::cout << Message << "\n";
if(argv[1][0] == 'b')
memGrab("before");
TCHAR *fileName = (TCHAR *)malloc(sizeof(TCHAR) * 1024);
IFileOpenDialog *pfd;
int index = 0;
int len = 0;
int i = 0;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pfd));
if(SUCCEEDED(hr)){
pfd->Show(NULL);
}
pfd->Release();
if(argv[1][0] == 'a')
memGrab("After");
}
CoUninitialize();
}
void memGrab(char *text){
for(int i = 0; i < 400000; i++){
if(!malloc(10240)){
char Message[128];
wsprintf(Message, "Memory Gone %s: %d K", text, i * 10);
std::cout << Message << "\n";
exit(0);
}
}
}
當我編譯該程序而不設置堆棧大小(cl testMem.cpp Shell32.lib Ole32.lib user32.lib
)。我得到以下結果:
C:\RWSource>testMem.exe b
Starting Memory Test: b
Memory Gone before: 1984040 K
C:\RWSource>testMem.exe a
Starting Memory Test: a
Memory Gone After: 1875640 K
但是,當我設置堆棧大小(cl testMem.cpp Shell32.lib Ole32.lib user32.lib /F100000000
)編譯它。我失去了大量的可分配內存。
C:\RWSource>testMem.exe b
Starting Memory Test: b
Memory Gone before: 1795370 K
C:\RWSource>testMem.exe a
Starting Memory Test: a
Memory Gone After: 463840 K
更新1:
我檢查用的VMMap內存(謝謝TheUndeadFish),當我打開的對話框中,有多個線程啓動的所有有關於100MB。有沒有辦法讓主線程有一個大的堆棧,而不是給每個線程100MB的線程?
更新2:
幾個月後我再次回到這個問題。我將主代碼移至另一個函數,並將其作爲具有指定堆棧大小的線程啓動。編譯時不需要堆棧大小。
int main(){
CreateThread(NULL, 100000000, analyze, NULL, 0, NULL);
// Wait for analyze thread.
}
int analyze(int ignore){
// Do stuff
}
爲什麼要將堆棧大小設置爲100 MB?對話框COM對象是否有可能產生自己的工作線程,這也可以獲得100 MB的堆棧?嘗試在使用Process Explorer或VMMap之前和之後查看它。 – Luke 2010-08-18 23:35:34
這就是發生了什麼,我如何讓所有的線程都達到100MB? – zmbush 2010-08-19 00:07:05
我不認爲你可以。如果調用者未明確指定堆棧大小(這很少完成),則CreateThread使用鏈接器在可執行文件中指定的堆棧大小。我能想到的唯一的事情就是使用默認值併產生自己的線程來指定所需的堆棧大小。 – Luke 2010-08-19 03:16:23