Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Динамический массив


Автор: devmstr 11.6.2004, 09:49
Если я создал динамический массив, то чистит ли Delphi память после окончания работы программы...

Автор: Петрович 11.6.2004, 10:25
Да. Более того, чистит не по окончанию программы, а тогда, когда переменная (динамический моссив) становится недоступной по области видимости. Т.е. например когда динамический массив в локальной переменной процедуры X, то память выделенная под него, освобождается автоматически при завершении процедуры X.

Автор: Guest 11.6.2004, 11:00
Спасибо

Автор: x77 11.6.2004, 17:14
Петрович , я всегда делал так:
Код
var
 m: array of string;
begin
 SetLength (m, 10);
 try
   ...
 finally
   Finalize (m);
 end;
end;



ты хочешь сказать, что освобождать память руками не надо в принципе? сказал, SetLength (m, 200000) и забыл?

Автор: Cheba 11.6.2004, 22:11
Цитата
чистит не по окончанию программы, а тогда, когда переменная (динамический моссив) становится недоступной по области видимости

А с екземплярами классов такое происходит?

Автор: x77 11.6.2004, 22:30
Cheba, нет. при создании экземпляра класса указывается его владелец (owner). при уничтожении объекта он сам уничтожит все свои дочерние объекты. если вместо owner был указан nil, то уничтожать придётся руками, самому.

Автор: Она 11.6.2004, 22:30
Cheba , если под экземплярами классов ты понимаешь сам объектный код классов, а не объекты , породленные от того или иного класса, то как и с любым объектником выгрузка этого кода- проблема операционной системы. если же говорить говорить об объектах ( или экземплярах), то это либо проблема VCL, в случае, если ты не пораждаешь объекты динамически, или пользуешься только наследниками TComponent, причем не указываешь в качестве овнера nil.
Все объекты не порожденные от TComponent или объекты с неуказанным владельцем (nil)- твоя проблема.

Автор: youri 12.6.2004, 14:58
Цитата
Более того, чистит не по окончанию программы, а тогда, когда переменная (динамический моссив) становится недоступной по области видимости.

Да, по-моему, Петрович на Java перепрограммировал (всякие там сборщики мусора)

Цитата
ты хочешь сказать, что освобождать память руками не надо в принципе?

Я согласен, что надо, но я так понимаю при завершении программы Windows все равно вернет себе эту память?

Автор: _hunter 12.6.2004, 15:50
вернуть то они вернут, но если приложение работает месяц и каждый час теряет по кило -- плохо окнам будет smile.gif

Автор: youri 12.6.2004, 20:45
Полностью с тобой согласен (просто хотел уточнить)

Автор: Jey_k 13.6.2004, 21:19
Можно ограничить адресацию памяти программой

Автор: x77 13.6.2004, 22:27
_hunter, нифига они не вернут. сделай GetMem (p, Size) и получишь классический memory leak при закрытии.

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

Автор: Она 14.6.2004, 00:59
Господа, начиная с пятой версии делфы , работает 24*365, и все при этом совершенно спокойно...
Сами понимаете проблема не в системе, и не в средстве. Гы smile.gif

Автор: x77 14.6.2004, 01:10
Она, не понял. что именно работает сов. спокойно?

Автор: Jey_k 14.6.2004, 10:13
x77
Э-э батенька вы полуось с виндой не путайте

Автор: _hunter 14.6.2004, 19:11
ага smile.gif :
Цитата
This function allocates a new memory block from OS/2, then adds it to the heap.  The allocation is performed by committing pages that have been previously allocated from the virtual address space but not committed. The block size is rounded up to the next multiple of 64K.  Virtual address space is allocated in multiples of 4 Meg, and committed in multiples of 64K.

+ IMHO пмять, выделенная под прогу с прогой и освободится ( если ее не выделить в другом процессе ( что аналогично ) )

Автор: youri 15.6.2004, 04:05
Цитата
которую для неё выделила ось

Цитата
This function allocates a new memory block from OS/2

Люди, а вы что про OS/2 говорите (когда я встретил первый фрагмент, а думал имеется в виду операционная система)?

Автор: x77 15.6.2004, 12:42
я говорил именно про ось, а не про ось-пополам. а осью я называю любую операционку, сорри за неточности.

народ, мне уже интересно. т.е. если прога делает GetMem, New, GlobalAlloc и пр. всего один или несколько раз, не в цикле, и переполнения кучи гарантированно не произойдёт, то я могу смело не вызывать FreeMem и протчая?

т.е. я могу сделать GetMem (p, size), потом GetMem (p, size2), FreeMem (p, size2) и память, выделенная первым GetMem тоже будет освобождена при выходе из программы?

Автор: p0s0l 15.6.2004, 14:43
Цитата
Да, по-моему, Петрович на Java перепрограммировал (всякие там сборщики мусора)

Он сказал всё правильно. Дин. массивы (и дин. строки) автоуничтожаются.
Локальные - перед выходом из функции/процедуры.
Глобальные - при завершении работы программы (Finalization юнита).

Цитата
т.е. я могу сделать GetMem (p, size), потом GetMem (p, size2), FreeMem (p, size2) и память, выделенная первым GetMem тоже будет освобождена при выходе из программы?

Да. За этим следит менеджер памяти дельфинской проги. Каждый вызов GetMem запоминается, и при завершении проги вызывается процедура UninitAllocator, которая в цикле для каждого неосвобожденного GetMem'а вызывает VirtualFree...
Если же юзать VirtualAlloc или др. API вместо GetMem, то за освобождением памяти будет следить уже сама винда - при уничтожении процесса автоматически уничтожатся все выделенные процессу (уже ненужные) ресурсы, в т.ч. и память.

Наверняка многие видали игры, в которых если долго играть, начинаются тормоза, подгрузки. Это недосмотры программеров - memory leaks. Дело решается перезапуском игры, т.к. при закрытии игры винда сама "подчищает" за игрой.

Автор: x77 15.6.2004, 15:13
круто. век живи, век учись.

p0s0l, с возвращением ;)

Автор: Jey_k 15.6.2004, 17:49
Вообще лучше обнулять все выделенное ранее. Сколько раз сталкивался с тем что происходит наложение данных.

Автор: Cheba 15.6.2004, 17:58
p0s0l, так что, memory leak в принципе не возможен, если не использовать хитрых методов отбирания памяти у других процессов?

Автор: x77 15.6.2004, 18:17
смотря что понимать под утечкой. например, при щелчке на кнопку происходит считывание списка файлов текущего каталога в глобальный динамический массив. если юзер щёлкнул на кнопку пару раз и закрыл прогу - фиг с ним. а если прога непрерывно работает месяц? и юзер постоянно щёлкает? память не освобождается, т.е. ос будет по честному пытаться каждый раз выделить дополнительную память, когда она заканчивается. начинаются подкачки со свапа и т.д. вот об этом и говорил p0s0l. просто я был уверен, что вся эта память при закрытии проги так и останется заюзанной, в чём был неправ.

Автор: p0s0l 16.6.2004, 20:47
Цитата
p0s0l, с возвращением ;)

Да не, я заглянул сюда когда выдалось время. У меня еще полсессии впереди. Каждый день вспоминаю о форуме, но воздерживаюсь (еле-еле) smile.gif

Цитата
p0s0l, так что, memory leak в принципе не возможен

Ну да. У процесса после его создания ничего не имеется, кроме одного потока и нескольких ресурсов. Для того, чтобы что-нибудь заиметь, процесс должен сделать запрос у ОС. ОС не дура - чтобы потом вернуть запрошенные ресуры обратно, запоминает "должок" процесса у себя. Этот факт подтверждает то, что имеются стандартные средства узнать, какие ресурсы (файлы, память, семафоры и др.) используют другие процессы (см. SysInternals) - это говорит о том, что винда запоминает всё, что кто-либо использует, в том числе и сама винда тоже.
Если процесс при завершении работы забыл что-то отдать обратно, ОС сама себе вернёт это принудительным образом... Конечно, она работает по определённым правилам (уничтожаются только ненужные никому ресурсы, т.е. если какой-либо ресурс юзают два процесса, то он уничтожится только после закрытия обоих процессов, или когда оба процесса его освободят), поэтому её можно обмануть. Например, открываем файл, делаем DuplicateHandle, причём процесс-приёмник будет какой-нибудь Explorer.exe (хотя нафиг сдался ему этот файл?). Теперь после закрытия проги файл останется всё равно открытым, а если он открыт эксклюзивно, никто его ни удалить, ни посмотреть даже не сможет. Теперь файл закроется, только если убить процесс explorer.exe.
Но это были файлы. А что если делаем так:
CreateFileMapping(INVALID_HANDLE_VALUE, ...., 128*1024*1024, 'MyMapping');
Потом делаем DuplicateHandle...
Теперь если прога закроется, то эти выделенные 128 метров памяти так и останутся висеть. Хэндл мы продублировали, хотя процессу, для которого мы дублировали хэндл нафиг этот файл-маппинг не нужен smile.gif.
Это, кстати, можно использовать в своих целях, если надо хранить какую-то инфу только в текущей сессии, и чтобы эта инфа не терялась после завершения нашей проги...

Автор: Cheba 16.6.2004, 22:57
p0s0l, спасибо. smile.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)