Текущий архив: 2005.09.11;
Скачать: CL | DM;
ВнизОсвобождение памяти при Destroy Найти похожие ветки
← →
afanasic (2005-08-11 08:48) [0]Доброго времени суток, уважаемые мастера!
Вопрос такого плана:
В коде программы все формы кроме главной появляются таким образом:
function ShowNeedForm(Owner: TForm): Boolean;
begin
with TNeedForm.Create(Owner) do
try
Result := ShowModal = mrOK;
finally
Destroy; {Free;}
end;
end;
Почему до первого показа формы программа занимает в памяти X kb,
во время показа X+m kb, m>0, а после Destoy (Free) - X+k kb, k>0, причем k сопоставимо по значению с m, и если и меньше, то ненамного? И при показе разных форм все эти ненужные объемы памяти накапливаются. Почему???
← →
Думкин © (2005-08-11 08:55) [1]какой памяти?
← →
evvcom © (2005-08-11 09:16) [2]Тебя это напрягает?
← →
Digitman © (2005-08-11 09:21) [3]
> afanasic (11.08.05 08:48)
Это - особенность BMM (Borland Memory Manager)
Алгоритм работы ВММ оптимизирован для работы с множеством небольших по размеру повторно используемых фрагментов памяти
При запросе программы на выделение блока памяти в М кб ВММ делает следующее :
1. ищет в контролируемом им списке подходящий незанятый блок размером не меньше М кб,
2. при нахождении усекает его до М кб (остаток помечается как новый отдельный свободный блок) и возвращает его программе, пометив как занятый
3. при ненахождении запрашивает у системы из "кучи" (heap) процесса блок размера кратного 4к (но не менее М кб), помечает его как незанятый и далее см. 2
При запросе программы на освобождение ранее запрошенного и выделенного менеджером блока памяти ВММ делает следующее :
1. помечает освобождаемы й блок как более незанятый
2. если "сверху" и "снизу" освобожденного блока есть смежные незанятые блоки, объединяет их в единый незанятый блок суммарного размера
3. в "кучу" освобожденные блоки менеджером блоки НЕ возвращаются
Операции работы с кучей (запрос памяти из кучи, перераспределение/освобождение ранее запрошенных блоков) ощутимо менее производительны, нежели аналогичные по целевой функц-ти операции работы со списком "блоков", организованным ранее в УЖЕ запрошенной из кучи памяти
Это своего рода "кэширование памяти" (прикладное), значительно увеличивающее сквозную производительность приложения, интенсивно обращающегося в ходе своей работы в ресурсам вирт.памяти своего процесса.
Т.о., если , например, при создании/визуализации некоей формы приложение затребовало у ВММ 5к байт памяти, а в распоряжении ВММ на этот момент находится своб.блок размеров в 4к, ВММ запросит из кучи еще 8к, и из них "отдаст" приложению 5к (остаток в 3к пометит как свободный блок)... Далее при разрушении формы приложение "вернет" менеджеру эти 5к, и менеджер объединит 5к + 3к в своб.блок размером в 8к
Если теперь последующее создание/визуализация другой формы потребует у ВММ, к примеру, 7к памяти, ВММ уже не будет обращаться к куче, а возьмет их из уже имеющегося в его распоряжении блока в 8к - 7к пометит как занятые, а остаток в 1к пометит как свободный блок
приведенная схема работы ВММ, конечно же, сильно упрощена, но иллюстрирует работу ВММ как "посредника" между прикладной задачей и системой.
← →
Defunct © (2005-08-11 09:26) [4]это конечно погоды не построит вообще и к вопросу как бы не относится, но я бы писал (коль уж не нужен результат модальной формы) не так
> Result := ShowModal = mrOK;
а так
ShowModal;
> все эти ненужные объемы памяти накапливаются. Почему???
Вариант 1.
Ошибка в программе. В модальных формах что-то создается и не разрушается.
Вариант 2.
Небо голубое, вода мокрая. А менеджер памяти не считает нужным освобождать занятую память. Знаете такое понятие как кеш. Вот это нечто схожее. Вы выделили память, а потом зачем ее освобождать если не просят? Вдруг придется еще раз выделять, так уж подержим чтоб лишний раз систему не дергать.
← →
afanasic (2005-08-11 09:26) [5]> какой памяти?
Оперативной, той которую занимает программа, той, которая отображается в Диспетчере задач...
>Тебя это напрягает?
Отчасти напрягает, отчасти интересно, почему так? Дело в том, что основное окно занимает всего 100 kB(при начальном запуске), а открытие всяких форм редактирования (и их последующее закрытие)увеличивает объем программы в разы (до 1.5 Mb), что слишком много и не нужно...
← →
Digitman © (2005-08-11 09:39) [6]
> открытие всяких форм редактирования (и их последующее закрытие)увеличивает
> объем программы в разы (до 1.5 Mb), что слишком много и
> не нужно
и при этом с каждым открытием/закрытием объем используемых ресурсов памяти процесса неуклонно растет ?
если так, то следует призадуматься над заведомо имеющимися ошибками в своей программе, приводящими к утечкам ресурсов памяти
← →
afanasic (2005-08-11 09:40) [7]> Defunct
Спасибо!
Достаточно понятно!
Дело в том, что в программе важно только главное окно - оно висит на экране и показывает кучу полезной информации. Кроме него есть еще две формы - О программе (с рисунком - TImage) и форма настроек параметров отображения информации. В этих формах в динамике не создается ничего. Функция простая - показать/убрать (О программе) или прочитать/показать/сохранить/убрать (параметры). Модальный результат важен, чтобы знать, обновлять данные на основной форме, или нет. И даже при такой простой схеме память съедается.
Просто неприятно - если пользователь всего лишь посмотрел пункт "о программе" - а программа БАХ и увеличилась, потом - поредактировал параметры - она снова увеличилась. Делаются такие процедуры по идее нечасто и хранить выделенную память для них нет смысла - лучше лишний раз дернуть систему. Программка мизерная, поэтому проблема вроде бы не стоит, но крупных проектах (за 50 форм) это уже важно.
Можно ли принудительно освободить эту память?
← →
Digitman © (2005-08-11 09:44) [8]
> Можно ли принудительно освободить эту память?
как крайняя мера см. SetProcessWorkingSetSize()
← →
afanasic (2005-08-11 09:44) [9]> Digitman
Спасибо! (перепутал авторов ответов:-))
Протестировал еще раз - действительно память растет только если отрывается форма с большими ресурсами, в остальном не растет и стопорится где-то на 1.8 Мб. Но по сравнению со 100 кб это очень много и не нужно, поэтому проблема еще стоит.
← →
Думкин © (2005-08-11 09:46) [10]> [9] afanasic (11.08.05 09:44)
перед кем стоит и какая проблема?
← →
Digitman © (2005-08-11 09:59) [11]
> afanasic (11.08.05 09:44) [9]
> память растет только если отрывается форма с большими ресурсами
значит в коде этой формы что-то не в порядке - где-то там происходит утечка памяти
← →
afanasic (2005-08-11 10:24) [12]ОК! Поищу... Но просто негде искать...
← →
Digitman © (2005-08-11 10:27) [13]
> afanasic (11.08.05 10:24) [12]
как это негде ?
какие компоненты и как используешь для этой формы ?
какие события формы/компонентов формы и как обрабатываешь ?
← →
afanasic (2005-08-11 10:40) [14]Компоненты:
TButton,
TSpeedButton,
TCheckBox,
TRadioButton,
TEdit,
TSpinEdit,
TImage,
TPanel,
TGroupBox,
TLabel;
FormShow: Данные из Ini-файла распихиваем по компонентам
btOkClick: Данные из компонентов запихиваем в Ini-файл,
Ini-файл создается один раз при старте главной формы.
Любая форма создается явно под fmMain.
Где здесь может быть утечка - все компоненты стандартные...
Причем, была бы утечка - память, занимаемая программой росла бы постоянно, а она стабилизируется на 1.8 Мб... Поэтому дело не в программе и в распределении памяти.
← →
Digitman © (2005-08-11 10:46) [15]
> была бы утечка - память, занимаемая программой росла бы
> постоянно, а она стабилизируется на 1.8 Мб
ну раз стабилизируется, значит нет повода для тревоги
к тому же 1.8 Мб - это просто мизерное значение
← →
afanasic (2005-08-11 10:58) [16]Да, но ведь реальное состояние при загрузке 100 кб - хотелось бы занимать их, лишние 1.7 мб мне не нужны и могут пригодиться в другом месте...
Ну ладно, раз никак не решить, значит будем стимулировать производителей памяти :-)
Всем спасибо за ответы!
← →
имя (2005-08-19 14:55) [17]Удалено модератором
← →
Плохиш © (2005-08-19 15:10) [18]
> afanasic (11.08.05 10:58) [16]
> Да, но ведь реальное состояние при загрузке 100 кб - хотелось
> бы занимать их, лишние 1.7 мб мне не нужны и могут пригодиться
> в другом месте
Осталось почитать про распределение памяти в многозадачных системах :-)
← →
Desdechado © (2005-08-19 17:22) [19]вот здесь, имхо, правильней использовать Release
finally
Destroy; {Free;}
end;
← →
Lamer@fools.ua © (2005-08-19 18:49) [20]>>Desdechado © (19.08.05 17:22) [19]
Release() нужен, когда выполняется метод уничтожаемого объекта. Здесь такая ситуация не наблюдается.
← →
Anatoly Podgoretsky © (2005-08-19 19:18) [21]afanasic (11.08.05 09:26) [5]
> какой памяти?
Оперативной, той которую занимает программа, той, которая отображается в Диспетчере задач...
Оперативную память программа не занимает, это прерогатива системы, ее менеджера памяти.
Страницы: 1 вся ветка
Текущий архив: 2005.09.11;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.012 c