Если бы все реализовали интерфейс, это было бы сборкой мусора? - PullRequest
7 голосов
/ 17 сентября 2009

Я все еще новичок, и я знаю, что мое мышление неверно; Я просто не знаю , где ...

Практически все в Delphi происходит от TObject. Что, если все вместо этого происходит от объекта TInterfaceObject, в котором реализован какой-то тривиальный интерфейс (например, «INamable» с одним методом, который возвращает строку имени класса)? Поскольку TObject уже имеет свойство, которое возвращает строку имени, вам не нужно ничего добавлять в дополнительные классы.

Другими словами, TInterfacedObject наследовал бы от TObject (или что-то высоко в иерархии), и все, что в настоящее время происходит от TObject, теперь будет происходить из этого нового класса. Разве это не значит, что теперь все подсчитано?

Если вы заметите, где не хватает моих знаний, я бы с удовольствием учился. Спасибо, как всегда - Эл С.

Ответы [ 5 ]

8 голосов
/ 17 сентября 2009

Не ясно, спрашиваете ли вы:

  • Почему Borland не сделал этого, когда они изначально разработали Delphi?
  • Почему бы Embarcadero не сделать это в будущей версии Delphi?
  • Почему бы мне не сделать это с моими собственными типами пользовательских данных?

Разве это не значит, что теперь все подсчитано?

Да, будет.

Однако вы не обязательно хотите, чтобы все было пересчитано: каждое маленькое целое число, каждая строка, каждый логический элемент, каждый элемент в массиве ... если нет другой причины, по которой реализация подсчета ссылок добавляет некоторые накладные расходы, например, немного дополнительной памяти на объект, возможно, незначительной для крупных объектов, но пропорционально более значимой, если применять ее к каждому крошечному объекту.

Также см. Также Сборщик мусора для объектов и компонентов Delphi , в котором говорится (цитата),

Delphi предоставляет три способа управления объектами:

  1. Создание / уничтожение объектов с помощью try..finally.
  2. Использовать потомков TComponent - создайте компонент и дайте его владельцу освободить его.
  3. Интерфейсы - когда счетчик ссылок для интерфейса становится равным 0, объект, который реализует это уничтожены.

В справке Delphi сказано, что не стоит смешивать подход владельца TComponent с интерфейс управления памятью, но ...

Это будет сборка мусора?

Не совсем; простой подсчет ссылок не так надежен, как сборка мусора:

  • При подсчете ссылок, если у вас есть два экземпляра с подсчетом ссылок, каждый из которых содержит ссылку на другой, они не освобождаются автоматически. Чтобы освободить их, вам нужно будет разорвать эту «циклическую ссылку» (т. Е. Явным образом попросить одного из них освободить ссылку на другого).

  • При истинной сборке мусора сборщик мусора заметит, что на эти два экземпляра не ссылаются откуда-либо еще, и освободит их обоих.

Обновление
Если вы аннотируете свои потенциально циклические ссылки как [weak] ссылки, то они будут уничтожены нормально. Но до Delphi 10.1 Berlin это работает только в компиляторах NexGen (то есть тех, которые используют LLVM под капотом). Начиная с 10.1 Берлина эти [weak] ссылки работают везде.

5 голосов
/ 17 сентября 2009

Это не будет работать сборщик мусора, потому что интерфейсы используют очень простую систему подсчета ссылок, а циклические ссылки, которые очень распространены в коде Delphi, нарушают простой подсчет ссылок.

3 голосов
/ 17 сентября 2009

Нет, из-за двух вещей:

  1. Даже если класс реализует интерфейс, он не делает его автоматически подсчитанным. Только если вы фактически используете его для реализации этого интерфейса, подсчет ссылок будет иметь какой-либо эффект.
  2. Как уже говорили другие: подсчет ссылок в интерфейсах приведет к немедленному освобождению экземпляра класса, когда счетчик ссылок достигнет 0. Это неявный вызов метода Free в этой точке кода. Это потерпит неудачу, например если два объекта ссылаются друг на друга. Подлинная сборка мусора освобождает объекты не тогда, когда они выходят из области видимости, а когда требуется память, поэтому при каждом обращении к счетчику не происходит никакого влияния на производительность, поскольку объект просто продолжает существовать. Кроме того, хороший сборщик мусора обнаружит изолированные циклические ссылки (например, ссылки A ссылаются на ссылки C, но ничто другое не ссылается на эти объекты) и также освободит эти объекты.
2 голосов
/ 17 сентября 2009

Сборка мусора отличается от простого подсчета ссылок. У вас может быть автоматическое удаление, когда счетчик ссылок достигает 0, но это тоже не сборщик мусора. Сборка мусора означает отказ от вашей способности контролировать, когда что-либо удаляется из памяти, и возможность реализации базового языка для оптимизации настроек. Вы перестаете обращать внимание на количество ссылок и доверяете динамическому поведению конкретной реализации сборки мусора.

Естественно, сборщик мусора использует систему подсчета ссылок, чтобы узнать, когда на что-то больше нет ссылок, но это маленький кусочек головоломки.

1 голос
/ 17 сентября 2009

Подсчет ссылок является формой сборки мусора, но не очень хорошей. Он используется некоторыми языками (я думаю, python), хотя часто с определением цикла.

Даже если вы произошли от TInterfaceObject, объект не учитывается при подсчете ссылок и поэтому не собирает мусор, если только вы не используете ссылку на интерфейс, а не ссылку на объект.

т.е. вам нужно будет использовать

Var 
  nameable: IMyInterface;
begin
  nameable:= IMyInterface.Create();
  nameable.x(y);
  etc
end;

Это означает, что ваш интерфейс должен уже поддерживать требуемые вам методы и свойства, которые быстро становятся утомительными, поскольку вам нужно создать интерфейс для каждого класса.

Это может быть сделано достаточно легко в D2009 или позже. См. Имплиментацию Барри Келли умных указателей . Тем не менее, применяются обычные ссылки cavets.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...