Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Освобождение памяти при Destroy [D6, D7, Win2k, WinXP]


Страницы:   1 2

afanasic ©   (2005-08-11 08:48:00) 

Доброго времени суток, уважаемые мастера!
Вопрос такого плана:
 В коде программы все формы кроме главной появляются таким образом:

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, и если и меньше, то ненамного? И при показе разных форм все эти ненужные объемы памяти накапливаются. Почему???


Anatoly Podgoretsky   (2005-08-19 19:18:00) [1]

afanasic   (11.08.05 09:26) [5]
> какой памяти?
Оперативной, той которую занимает программа, той, которая отображается в Диспетчере задач...

Оперативную память программа не занимает, это прерогатива системы, ее менеджера памяти.


Lamer@fools.ua   (2005-08-19 18:49:00) [2]

>> Desdechado ©   (19.08.05 17:22) [19]

Release() нужен, когда выполняется метод уничтожаемогообъекта. Здесь такая ситуация не наблюдается.


Desdechado   (2005-08-19 17:22:00) [3]

вот здесь, имхо, правильней использовать Release
finally
 Destroy; {Free;}
end;


Плохиш   (2005-08-19 15:10:00) [4]


> afanasic   (11.08.05 10:58) [16]
> Да, но ведь реальное состояние при загрузке 100 кб - хотелось
> бы занимать их, лишние 1.7 мб мне не нужны и могут пригодиться
> в другом месте

Осталось почитать про распределение памяти в многозадачных системах :-)


  (2005-08-19 14:55:00) [5]

Удалено модератором


afanasic   (2005-08-11 10:58:00) [6]

Да, но ведь реальное состояние при загрузке 100 кб - хотелось бы занимать их, лишние 1.7 мб мне не нужны и могут пригодиться в другом месте...
Ну ладно, раз никак не решить, значит будем стимулировать производителей памяти :-)

Всем спасибо за ответы!


Digitman   (2005-08-11 10:46:00) [7]


> была бы утечка - память, занимаемая программой росла бы
> постоянно, а она стабилизируется на 1.8 Мб


ну раз стабилизируется, значит нет повода для тревоги

к тому же 1.8 Мб - это просто мизерное значение


afanasic   (2005-08-11 10:40:00) [8]

Компоненты:
 TButton,
 TSpeedButton,
 TCheckBox,
 TRadioButton,
 TEdit,
 TSpinEdit,
 TImage,
 TPanel,
 TGroupBox,
 TLabel;
FormShow: Данные из Ini-файла распихиваем по компонентам
btOkClick: Данные из компонентов запихиваем в Ini-файл,
Ini-файл создается один раз при старте главной формы.
Любая форма создается явно под fmMain.

Где здесь может быть утечка - все компоненты стандартные...
Причем, была бы утечка - память, занимаемая программой росла бы постоянно, а она стабилизируется на 1.8 Мб... Поэтому дело не в программе и в распределении памяти.


Digitman   (2005-08-11 10:27:00) [9]


> afanasic   (11.08.05 10:24) [12]


как это негде ?

какие компоненты и как используешь для этой формы ?

какие события формы/компонентов формы и как обрабатываешь ?


afanasic   (2005-08-11 10:24:00) [10]

ОК! Поищу... Но просто негде искать...


Digitman   (2005-08-11 09:59:00) [11]


> afanasic   (11.08.05 09:44) [9]


> память растет только если отрывается форма с большими ресурсами


значит в коде этой формы что-то не в порядке - где-то там происходит утечка памяти


Думкин   (2005-08-11 09:46:00) [12]

> [9] afanasic   (11.08.05 09:44)

перед кем стоит и какая проблема?


afanasic   (2005-08-11 09:44:00) [13]

> Digitman
Спасибо! (перепутал авторов ответов:-))
Протестировал еще раз - действительно память растет только если отрывается форма с большими ресурсами, в остальном не растет и стопорится где-то на 1.8 Мб. Но по сравнению со 100 кб это очень много и не нужно, поэтому проблема еще стоит.


Digitman   (2005-08-11 09:44:00) [14]


> Можно ли принудительно освободить эту память?


как крайняя мера см. SetProcessWorkingSetSize()


afanasic   (2005-08-11 09:40:00) [15]

> Defunct
Спасибо!
Достаточно понятно!
Дело в том, что в программе важно только главное окно - оно висит на экране и показывает кучу полезной информации. Кроме него есть еще две формы - О программе (с рисунком - TImage) и форма настроек параметров отображения информации. В этих формах в динамике не создается ничего. Функция простая - показать/убрать (О программе) или прочитать/показать/сохранить/убрать (параметры). Модальный результат важен, чтобы знать, обновлять данные на основной форме, или нет. И даже при такой простой схеме память съедается.
 Просто неприятно - если пользователь всего лишь посмотрел пункт "о программе" - а программа БАХ и увеличилась, потом - поредактировал параметры - она снова увеличилась. Делаются такие процедуры по идее нечасто и хранить выделенную память для них нет смысла - лучше лишний раз дернуть систему. Программка мизерная, поэтому проблема вроде бы не стоит, но крупных проектах (за 50 форм) это уже важно.
 Можно ли принудительно освободить эту память?


Digitman   (2005-08-11 09:39:00) [16]


> открытие всяких форм редактирования (и их последующее закрытие)увеличивает
> объем программы в разы (до 1.5 Mb), что слишком много и
> не нужно


и при этом с каждым открытием/закрытием объем используемых ресурсов памяти процесса неуклонно растет ?

если так, то следует призадуматься над заведомо имеющимися ошибками в своей программе, приводящими к утечкам ресурсов памяти


afanasic   (2005-08-11 09:26:00) [17]

> какой памяти?
Оперативной, той которую занимает программа, той, которая отображается в Диспетчере задач...

>Тебя это напрягает?
Отчасти напрягает, отчасти интересно, почему так? Дело в том, что основное окно занимает всего 100 kB(при начальном запуске), а открытие всяких форм редактирования (и их последующее закрытие)увеличивает объем программы в разы (до 1.5 Mb), что слишком много и не нужно...


Defunct   (2005-08-11 09:26:00) [18]

это конечно погоды не построит вообще и к вопросу как бы не относится, но я бы писал (коль уж не нужен результат модальной формы) не так

> Result := ShowModal = mrOK;
а так
 ShowModal;

> все эти ненужные объемы памяти накапливаются. Почему???
Вариант 1.
Ошибка в программе. В модальных формах что-то создается и не разрушается.

Вариант 2.
Небо голубое, вода мокрая. А менеджер памяти не считает нужным освобождать занятую память. Знаете такое понятие как кеш. Вот это нечто схожее. Вы выделили память, а потом зачем ее освобождать если не просят? Вдруг придется еще раз выделять, так уж подержим чтоб лишний раз систему не дергать.


Digitman   (2005-08-11 09:21:00) [19]


> 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к пометит как свободный блок

приведенная схема работы ВММ, конечно же, сильно упрощена, но иллюстрирует работу ВММ как "посредника" между прикладной задачей и системой.


evvcom   (2005-08-11 09:16:00) [20]

Тебя это напрягает?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо