| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > 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 | ||
Петрович , я всегда делал так:
ты хочешь сказать, что освобождать память руками не надо в принципе? сказал, 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 |
| вернуть то они вернут, но если приложение работает месяц и каждый час теряет по кило -- плохо окнам будет |
| Автор: 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, и все при этом совершенно спокойно... Сами понимаете проблема не в системе, и не в средстве. Гы |
| Автор: x77 14.6.2004, 01:10 |
| Она, не понял. что именно работает сов. спокойно? |
| Автор: Jey_k 14.6.2004, 10:13 |
| x77 Э-э батенька вы полуось с виндой не путайте |
| Автор: _hunter 14.6.2004, 19:11 | ||
ага
+ IMHO пмять, выделенная под прогу с прогой и освободится ( если ее не выделить в другом процессе ( что аналогично ) ) |
| Автор: youri 15.6.2004, 04:05 | ||||
Люди, а вы что про 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 | ||||
Он сказал всё правильно. Дин. массивы (и дин. строки) автоуничтожаются. Локальные - перед выходом из функции/процедуры. Глобальные - при завершении работы программы (Finalization юнита).
Да. За этим следит менеджер памяти дельфинской проги. Каждый вызов 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 | ||||
Да не, я заглянул сюда когда выдалось время. У меня еще полсессии впереди. Каждый день вспоминаю о форуме, но воздерживаюсь (еле-еле)
Ну да. У процесса после его создания ничего не имеется, кроме одного потока и нескольких ресурсов. Для того, чтобы что-нибудь заиметь, процесс должен сделать запрос у ОС. ОС не дура - чтобы потом вернуть запрошенные ресуры обратно, запоминает "должок" процесса у себя. Этот факт подтверждает то, что имеются стандартные средства узнать, какие ресурсы (файлы, память, семафоры и др.) используют другие процессы (см. SysInternals) - это говорит о том, что винда запоминает всё, что кто-либо использует, в том числе и сама винда тоже. Если процесс при завершении работы забыл что-то отдать обратно, ОС сама себе вернёт это принудительным образом... Конечно, она работает по определённым правилам (уничтожаются только ненужные никому ресурсы, т.е. если какой-либо ресурс юзают два процесса, то он уничтожится только после закрытия обоих процессов, или когда оба процесса его освободят), поэтому её можно обмануть. Например, открываем файл, делаем DuplicateHandle, причём процесс-приёмник будет какой-нибудь Explorer.exe (хотя нафиг сдался ему этот файл?). Теперь после закрытия проги файл останется всё равно открытым, а если он открыт эксклюзивно, никто его ни удалить, ни посмотреть даже не сможет. Теперь файл закроется, только если убить процесс explorer.exe. Но это были файлы. А что если делаем так: CreateFileMapping(INVALID_HANDLE_VALUE, ...., 128*1024*1024, 'MyMapping'); Потом делаем DuplicateHandle... Теперь если прога закроется, то эти выделенные 128 метров памяти так и останутся висеть. Хэндл мы продублировали, хотя процессу, для которого мы дублировали хэндл нафиг этот файл-маппинг не нужен Это, кстати, можно использовать в своих целях, если надо хранить какую-то инфу только в текущей сессии, и чтобы эта инфа не терялась после завершения нашей проги... |
| Автор: Cheba 16.6.2004, 22:57 |
| p0s0l, спасибо. |