Размер занимаемой программой памяти
Вобщем так. Visual Studio 6.0, Win2000 Pro.
Элементарная программа, которая выводит окошко на экран. Простое окошко, пустое причем, абсолютно.
Всего две функции WinMain и WndProc. Никакой обработки событий, кроме WM_DESTROY и WM_TIMER.
Занимает в памяти (независимо от режима Debug или Relese) 1700 с копейками килобайт.
А когда по таймеру запускается WinAmp (пробовал только на нем :) ), то объем увеличивается до 2900 кБ. Для запуска использую ShellExecute.
Сейчас у меня 512 МБ ОЗУ и такой отнимаемый объем система переживет, но обидно как-то.
Как объем уменьшить?
И еще вопрос, вдогонку. Почему эта простейшая прога в Relese виде весит аж 24 кБ?
ЗЫ. У меня на работе стоит Small HTTP Server. Так он в неактивном режиме меньше 100 кБ занимает!
Тема изъезженная, знаю. Но пока сам не не столкнулся...
Вобщем так. Visual Studio 6.0, Win2000 Pro.
Элементарная программа, которая выводит окошко на экран. Простое окошко, пустое причем, абсолютно.
Всего две функции WinMain и WndProc. Никакой обработки событий, кроме WM_DESTROY и WM_TIMER.
Занимает в памяти (независимо от режима Debug или Relese) 1700 с копейками килобайт.
А когда по таймеру запускается WinAmp (пробовал только на нем :) ), то объем увеличивается до 2900 кБ. Для запуска использую ShellExecute.
Сейчас у меня 512 МБ ОЗУ и такой отнимаемый объем система переживет, но обидно как-то.
Как объем уменьшить?
И еще вопрос, вдогонку. Почему эта простейшая прога в Relese виде весит аж 24 кБ?
ЗЫ. У меня на работе стоит Small HTTP Server. Так он в неактивном режиме меньше 100 кБ занимает!
На первый вопрос с ходу не отвечу, а вот почему она весит 24к - потому что к ней автоматически прилинковывается CRT. Убрать это можно, собирая проект из командной строки.
На первый вопрос с ходу не отвечу, а вот почему она весит 24к - потому что к ней автоматически прилинковывается CRT. Убрать это можно, собирая проект из командной строки.
А можно отключить линковку CRT в настройках среды?
А можно отключить линковку CRT в настройках среды?
Я не нашел, как. В Project settings на закладке C/C++, Category Code Generation нет варианта Use run-time library None.
А можно отключить линковку CRT в настройках среды?
Да
#pragma comment(linker,"/ENTRY:entrypoint")
void entrypoint()
{
// отсюда начнётся ваща програма.
}
В таком случае размер будет 2,5 кб.
директива /entry:entrypoint
даёт компоновщику понять, что програму надо начинать с entrypoint()
Для примера смотри
http://freenet.am/~aramtt/My_Projects/MyDialogAppTemplate/
http://freenet.am/~aramtt/My_Projects/MyWindowAppTemplate/
И еще очень интересная статья.
http://rsdn.ru/article/cpp/crt.xml
можешь поиск по форуму поюзать. эту тему уже обсуждали.
Дык не нашел. Наверное не там искал.
И еще вопросик о занимаемой памяти в оперативе. Почему так много, то?
Да
#pragma comment(linker,"/ENTRY:entrypoint")
void entrypoint()
{
// отсюда начнётся ваща програма.
}
В таком случае размер будет 2,5 кб.
директива /entry:entrypoint
даёт компоновщику понять, что програму надо начинать с entrypoint()
Размер действительно стал меньше - 3 кБ. Но!
Диспетчер задач показывает, что программа работает, но окна нету :(
Размер действительно стал меньше - 3 кБ. Но!
Диспетчер задач показывает, что программа работает, но окна нету :(
Наверняка что то сделали не так.
Покажите код, я исправлю ошибку.
Если не ошибаюсь, размер стэка по умолчанию равен 1 мб. Если ваша програма не будет использовать такой объём стэка и если в вашей програме нет рекурсии, тогда можете со специальной директивой уменьшить размер стэка.
ему надо - ну в зависимости от того, сколько
потребуется и контроль стека можно отключить,
вычисления его объёма написать самому и т. д.
Только сейчас не напишу как, так как ужасно в
сон клонит - но точно могу сказать что это есть
в книжке Д. М. Романовской, Т.В. Русса -
програмирование в среде С, там для С, но
в С++ покатит без проблем.
Наверняка что то сделали не так.
Покажите код, я исправлю ошибку.
Программка то элементарная...
//#pragma comment(linker,"/ENTRY:WinMain")
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
VOID WINAPI HandlerService(DWORD fdwControl);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE vInstance, LPSTR lpCmdLine, int nCmdShow) {
HWND hWnd;
MSG Msg;
WNDCLASS MyClass;
MyClass.style = CS_HREDRAW | CS_VREDRAW;
MyClass.lpfnWndProc = WndProc;
MyClass.cbClsExtra = 0;
MyClass.cbWndExtra = 0;
MyClass.hInstance = hInstance;
MyClass.hIcon = 0;
MyClass.hCursor = LoadCursor(NULL, IDC_ARROW);
MyClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
MyClass.lpszMenuName = 0;
MyClass.lpszClassName = "My Class";
RegisterClass(&MyClass);
hWnd = CreateWindow("My Class", "My title", WS_BORDER | CAPTION | WS_SYSMENU | WS_MINIMIZEBOX , 300, 200, 300, 200, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&Msg,NULL,0,0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
}
return 0;
}
Почитал http://rsdn.ru/article/cpp/crt.xml. Действительно очень интересная статья. Но так как из командной строки собирать лень :) , решил прописать параметры в настройках проекта. Единственное, что работает это параметр /MD. Также, как видно из кода, уменьшил выравнивание для секций. В результате размер стал 3,5 кБ. Если же убрать /MD и оставить #pragma comment(linker,"/ENTRY:WinMain"), то размер программы менее 3 кБ, но окошко не рисуется. Пробовал после каждой функции MessageBox поставить - ошибок нет.
ЗЫ. Размер программы в памяти, после этой оптимизации (/MD; изменение выравнивания ничего не дает), уменьшился на 60 кБ и составил 988 кБ (для программы в 3,5 кБ :) )
ЗЗЫ. А если еще и SetTimer воткнуть, 1700 кБ(!) будет.
Ведь если CRT выключено, то даже вместо параметров, в мою функцию будет мусор передаваться. Да и нормальное завершение программы будет невозможно. Поэтому на вопрос об невидимости окна прошу не отвечать.
Вот именно, я так и думал, что у вас такая проблема, потому что когда то я тоже сталкивался с ней. Вообще при отключении CRT не надо использовать WinMain(...).
Делайте так, как это делаю я в моих примерах.
Выше я дал на них ссылку.
Примерно так
#pragma comment(linker,"/ENTRY:main")
void main()
{
HINSTANCE AppInstance = GetModuleHandle(NULL); // возвращает instance программы
}
А помоему объём стэка компилятор выбирает как
ему надо - ну в зависимости от того, сколько
потребуется и контроль стека можно отключить,
вычисления его объёма написать самому и т. д.
Только сейчас не напишу как, так как ужасно в
сон клонит - но точно могу сказать что это есть
в книжке Д. М. Романовской, Т.В. Русса -
програмирование в среде С, там для С, но
в С++ покатит без проблем.
Search in MSDN by index name "/STACK linker option"
А для выхода из программы используй ExitProcess(0);
:) Ну вообщем именно так я и сделал, как только понял ошибку. А по поводу объема занимаемой ОЗУ ничего не подскажете? Я пытался в поисковиках искать, но ничего не нашел, честное слово :)
Программка то элементарная...
Размер программы в памяти, после этой оптимизации (/MD; изменение выравнивания ничего не дает), уменьшился на 60 кБ и составил 988 кБ (для программы в 3,5 кБ :) )
ЗЗЫ. А если еще и SetTimer воткнуть, 1700 кБ(!) будет.
А как Вы определяете сколько ваша программа занимает в памяти. Я перепробовал все показатели диспетчера задач - все они какие-то мудрёные: рабочее множество (Mem Usage) прыгает при свёртывании и развёртывании программы, VM size я так и не понял что означает при том, что прекрасно понимаю, что такое виртуальная память и то, что она включает в себя физическую память (ОЗУ), ну и т.д.
прошу меня просветить.
А как Вы определяете сколько ваша программа занимает в памяти. Я перепробовал все показатели диспетчера задач - все они какие-то мудрёные: рабочее множество (Mem Usage) прыгает при свёртывании и развёртывании программы, VM size я так и не понял что означает при том, что прекрасно понимаю, что такое виртуальная память и то, что она включает в себя физическую память (ОЗУ), ну и т.д.
прошу меня просветить.
И ещё: пробую использовать Process Eplorer. Прожка вроде как неплохая, но не могу понять, как в ней посмотреть показатели в байтах, а не в килобайтах. А то у меня счёт идёт на байты (речь идёт о программе-сервере для долговременной работы - если на каждом запросе от клиента будет теряться хотя бы байт, то через неделю сервак упадёт).
А как Вы определяете сколько ваша программа занимает в памяти. Я перепробовал все показатели диспетчера задач - все они какие-то мудрёные: рабочее множество (Mem Usage) прыгает при свёртывании и развёртывании программы, VM size я так и не понял что означает при том, что прекрасно понимаю, что такое виртуальная память и то, что она включает в себя физическую память (ОЗУ), ну и т.д.
прошу меня просветить.
Вообще-то я смотрел только на Mem Usage. И интересовал меня именно этот показатель.
Про свертывание/развертывание. По моим наблюдениям за программами при свертывании Mem Usage резко падает, а затем постепенно восстанавливается. И принимает начальное значение при развертывании. Чесно говоря я никогда не задавался вопросом что есть Mem Usage, но как я полагаю - это физически занимаемая программой память в оперативе в данный момент времени.
Вообще-то я смотрел только на Mem Usage. И интересовал меня именно этот показатель.
Про свертывание/развертывание. По моим наблюдениям за программами при свертывании Mem Usage резко падает, а затем постепенно восстанавливается. И принимает начальное значение при развертывании. Чесно говоря я никогда не задавался вопросом что есть Mem Usage, но как я полагаю - это физически занимаемая программой память в оперативе в данный момент времени.
Вот именно эта непонятица меня и бесит.
Кстати если прогу развернуть, то первоначально занятая ею память может и восстанавливается в начальное значение со временем, но не сразу, если программа не выполнит запрос на выделение новой памяти (только что проверил).
Вообще-то я смотрел только на Mem Usage. И интересовал меня именно этот показатель.
Про свертывание/развертывание. По моим наблюдениям за программами при свертывании Mem Usage резко падает, а затем постепенно восстанавливается. И принимает начальное значение при развертывании. Чесно говоря я никогда не задавался вопросом что есть Mem Usage, но как я полагаю - это физически занимаемая программой память в оперативе в данный момент времени.
Что бы там ни было, но вы оказались правы, что смотрели на этот параметр. Если прогу не сворачивать и не давать ей простаивать, то это точный показатель занимаемой прогой памяти. Причём вся эта занятая память - физическая (в ОЗУ), в свопе - 0 байт.
Да, давненько я не занимался программированием. А в последнее несколько месяцев и времени-то нет. Начал работь на себя :) - обслуживаю несколький компаний на предмет компов, ПО, сети и т.п. В колею, так сказать, немогу войти.
А теперь по делу. Поискав еще раз в сети нашел вот это:
http://www.gotdotnet.ru/DotNet/FAQ/CommonForum/Interop/524.aspx
Вот эта функция (SetProcessWorkingSetSize) мне тогда и была нужна. Вам же, с сервером, это вряд ли поможет.
Оффтоп.
Да, давненько я не занимался программированием. А в последнее несколько месяцев и времени-то нет. Начал работь на себя :) - обслуживаю несколький компаний на предмет компов, ПО, сети и т.п. В колею, так сказать, немогу войти.
А теперь по делу. Поискав еще раз в сети нашел вот это:
http://www.gotdotnet.ru/DotNet/FAQ/CommonForum/Interop/524.aspx
Вот эта функция (SetProcessWorkingSetSize) мне тогда и была нужна. Вам же, с сервером, это вряд ли поможет.
Мне более важным оказался параметр "размер невыгруженного страничного пула". Чётко меняется при вызовах new и delete.