Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.53 MB
Время: 0.042 c
1-1124177403
Arkady
2005-08-16 11:30
2005.09.11
TOpenDialog


3-1122618282
Jamik
2005-07-29 10:24
2005.09.11
Как можно изменить свойства ячейки Excel с помощю DDE


14-1124281539
oldman
2005-08-17 16:25
2005.09.11
Вчера умер Гомельский.


4-1121919319
Pearled
2005-07-21 08:15
2005.09.11
Количество напечатанных страниц


14-1124180776
Esu
2005-08-16 12:26
2005.09.11
Во блин кратер отгрохали :)