Сборщик мусора для Delphi |
Хочу предложить тему:
Сборщик мусора для Delphi.
По сравнению с java, где объект считается пригодным к удалению, когда на него нет ссылок.
в Delphi довольно не удобно управлять освобождением объектов:
обязательно существует "владелец" объекта, который должен его удалить вызывая метод Free.
Подобная проблема есть и в C++, однако для C++ есть библиотеки со сборщиками мусора.
Делал ли кто-нибудь такой сборщик мусора для Delphi? Есть ли другие пути повышения удобства
управления объектами? ниик
Всего в теме 28 сообщений
Добавить свое сообщение
Отслеживать это обсуждение
- Отладчик
- Как реализовать собственный Debugger для ActiveScript
<<<... | 18—9 | ...>>> Всего сообщений в теме: 28; страниц: 3; текущая страница: 2
№ 18 02-10-2001 11:44 | |
To Yriy
Ой, смотрю я на нашего монстрика на 200 тыс. строк и думаю -- сказали тебе бедняге, что ты работать не можешь, а тем более с такими объемами кот-е ты лопатишь -- гиговые данные, не будет тебе хватать ресурсов :). А он мне -- да нет хватает, бо когда меня писали всегда думали -- распределили память, как ее бум освобождать :).
Способов _правильного_ написания кода, кот-й не допустит утечки ресурсов много, но главная парадигма -- когда распределяешь ресурсы подумай когда и как освободишь. Я часто так и пишу :
SomeObject := TSomeObject.Create;
try
finally
SafeFreeObj(SomeObject);
end;
а потом уже внутри try пишу алгоритм.
Еще одной неплохой техникой является широкой использование классов для сложных алгоритмов. При этом класс отслеживает всех своих членов и деструкторе освобождает ресурсы.
Т.о. IMHO главный путь избежать утечек это грамотно проектировать и писать код !
Что касается замены менеджера памяти, то я продумывал (не реализовывал, ннет потребности) следующий вариант. Перед какой либо ресурсоемкой, изолированной и чреватой утечками памяти частью алгоритма ставим марочку. Менеджер памяти начинает маркировать все выделенные ресурсы этой марочкой. После завершения алгоритма, когда нам гарантированно ничего не нужно из выделенных русурсов просто говорим менеджеру, что б он освободил все ресурсы помеченные этой маркой. Получается полуавтоматический gc по требованию. Эту идею я не реализовавывал, а вот свой менеджер памяти, кот-й отслеживает и логгирует выделение/освобождение памяти мы используем в особо сложных случаях для того, что бы убедится в отсутсвии memory leaks.
№ 17 02-10-2001 11:30 | |
№ 16 02-10-2001 11:27 | |
Пример. Объект хранится в базе данных, надо открыть N его редакторов
Когда объект должен убиваться?
еще пример. (Что-нибуь похожее на TopLink)
type TCollection=class
// Создает коллекцию с отобранными из данной элементами по условию
// condition
where(condition):TCollection;
end
type TApp=class
users:TCollection;
end;
var App:TApp
showMessage(IntToStr(App.users.where('Enabled=false').count))
with App.users.where('Enabled=false') do
where('Name like "A%"').count
with where(Role.equalTo(Administrator).and(Created.lessThen('01.01.2001'))).iterate do
begin
while hasNext do
begin
showMessage(next.toString())
end;
end;
end;
Перепешите это со всеми Free...
№ 15 02-10-2001 08:55 | |
Ерунда все это.
Если необходимо создавать кучу обектов и удалять их когда не используются тогда
и следите за ними.
делается очень просто:
1) Создаете TList как глобальную переменную или private переменную главной формы.
2) Вместо конструкции with TForm.Create(nil) или т.п.
i:=TList.Add(TForm.Create(nil));
with TList.Item[I] do и проблема пропадает сама собой.
3) В деструкторе формы добавляете три строки:
I:=TList.Count
for y:=I-1 downto 0 do
TList.Item[y].Free
и все. Если требуется удалять объекты в процессе выполнения то находите их в TList и давите
№ 14 02-10-2001 08:49 | |
По моему идея о замене менеджера памяти не сработает. Я уже пробовал. Конечно таким образом можно хранить список указателей на выделенные фрагменты памяти, но невозможно будет определить память все еще нужна или уже нет. Может быть стоит начать обсуждение не столько с того "как сделать" сколько с того "что сделать". Что Вы хотите получить от сборщика мусора? Когда он дожен убивать объекты? И т.д.
Например если объект создается (вызовом конструктора или вызовом функции, возвращяющей ссылку на объект) и уничтожается в одной процедуре, то есть просто стандартное решение:
My := TMy.Create;
try
...
finally
My.Free;
end;
Я думаю, это все знают. Если это решение не нравиться из за большого количества вложенных try..finally, могу описать другое, более интересное решение.
А если речь не идет об объектах, живущих только в одной процедуре, то в определенный момент времени непонятно, объект все еще нужен или уже нет. Самое большее, что можно сделать, это хранить список всех созданных объектов (и то это можно сделать только для тех объектов, которые сам создаешь, а ведь кроме них еще существуют вложенные объекты или системные объекты, вроде Exception, которые сами собой создаются) и предоставить пользователю событие в котором он должен решать нужен еще этот объект или уже нет. Но по моему это породит ее большее колличество ошибок.
№ 13 02-10-2001 03:31 | |
To Serge.
Принцип "я объект породил, я его и убъю" -железный принцип и
надежный, вот только жаль ,что не универсальный. Отследить рождение
и смерть объектов классов типа TFORM ,TFRAMES и ему подобных даже в большом проекте не так уж и сложно (немного внимания и терпения) потому, что они в некотором роде статичны и их жизнедеятельность в
программе можно и нужно упорядочивать (разбивка проекта на модули, пакеты, библиотеки и т.д.).
Возмем иную ситуацию:сотни мелких динамических обьектов, которые необходимо постоянно создавать и вовремя уничтожать иначе возникнет проблема с ресурсами и притом , что объекты должны существовать не сами по себе,а быть в канве некоего алгоритма. Вот тут Ваш принцип не срабатывает, потому что после многодневных тестов пройдя по алгоритму
вдоль и поперек с принципом "создал-убил" добиваетесь безупречной работы от компонента говорите:"ВСЕ!!!".На следующее утро c благодушным настроением и чашкой кофе подключаете модуль к проекту и уже напоследок начинаете его дергать, а тут Вам Message о нехватке ресурсов и система падает с молчаливого согласия DELPHI и все начинается сначала.
Вывод: Все в мире, а уж тем более в программировании относительно. Что для одного проекта-благо для другого смерть. Но выбор должен быть. Так что я за сборщика мусора, но действия его должны быть прозрачны и понятны.
№ 12 01-10-2001 17:13 | |
To Ник
--
with TForm1.Create(Application) do ...
ссылок нет, а объект есть.
---
Перечитайте справку о параметре owner.
----
С таким же успехом
with TForm1.Create(nil) do ...
и никаких овнеров нету :).
Мне лично идея автоматической сборки мусора не нравится -- я объект породил, я его и убъю :).
А вот неавтоматическую никто не мешает сделать -- менеджер памяти в дельфях оч. легко подменяется своим :). Но тоже, опасное это дело ...
№ 11 01-10-2001 11:40 | |
----
with TForm1.Create(Application) do ...
ссылок нет, а объект есть.
---
Перечитайте справку о параметре owner.
№ 10 01-10-2001 11:38 | |
Я вообще-то знаю аргументы противников сборки мусора...
Так что мне не хотелось бы обсуждать нужна она или нет
(это много раз обсуждалось и я сделал свои выводы), а хотелось бы узнать, есть ли какие-нибудь библиотеки.
Подсчет ссылок (реализованный в COM) очень приблизительная замена сборки мусора. (Например, там есть проблема кольцевых ссылок)
PS. Если кто-то хочет узнать о сборщиках мусора по подробнее, вот неплохая ссылка
http://www.iecc.com/gclist/GC-faq.html
№ 9 28-09-2001 20:02 | |
А как насчет такой ситуации:
with TForm1.Create(Application) do ...
ссылок нет, а объект есть. Я согласен с Антоном Ковалевым. По моему не стоит идти в разрез всей системы. Проектировать программу правильно надо. Я бы даже не хотел, чтообы мой объект удалялся когда ему вздумается.
<<<... | 18—9 | ...>>> Всего сообщений в теме: 28; страниц: 3; текущая страница: 2
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|