Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];

Вниз

Освобождение памяти при 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.012 c
9-1115981864
Ландграф Павел
2005-05-13 14:57
2005.09.11
Ищу девочек и мальчиков для рисования вставок на flash`е


2-1123456671
TIGOS
2005-08-08 03:17
2005.09.11
Дурацкий вопрос. По-поводу конвертирования текст -> в Real


2-1123593226
DeepProg
2005-08-09 17:13
2005.09.11
ADOQuery.Open. SELECT


9-1115753319
Da Stranger
2005-05-10 23:28
2005.09.11
Система предотвращения столкновений


1-1123694728
Starcom
2005-08-10 21:25
2005.09.11
Как у MessageDlg сделать фон к примеру Белым?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский