2009-09-17 1 views
7

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

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

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

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

ответ

8

Это не ясно, будет ли вы спрашиваете:

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

это не значит ли все теперь подсчет ссылок?

Да, это так.

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

Кроме того, смотрите также Garbage Collector For Delphi Objects and Components, который говорит (цитирую),

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

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

помощь Delphi говорит, что вы не должны смешивать владелец подхода TComponent с управлением памятью интерфейса, но ...

Будет ли это сборкой мусора?

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

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

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

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

5

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

+0

Но это верно и для существующего подсчета ссылок. – ChrisW

+0

Да, в этом суть. –

+0

Я вижу, что он задает два вопроса. Я попытаюсь прояснить свой собственный ответ. – ChrisW

2

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

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

+2

Простой подсчет ссылок - это ФОРМА сбора мусора. Не очень хороший по всем счетам (но тогда, возможно, сбор мусора по своей сути ошибочен как технология общего назначения). Но очень успешная технология построена на полностью сопоставленной схеме сбора мусора («успешной» с точки зрения того, насколько широко она используется, и критичности систем, которые на ней опираются). Я говорю о COM, конечно. – Deltics

+1

Без сборщика мусора нет мусора. Сбор мусора - это отсроченное действие освобождения памяти только после того, как никто больше не ссылается на нее. Только использование счетчиков ref - это форма управления памятью. – Kieveli

1

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

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

I.e. Вы должны были бы использовать

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

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

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

+0

Это будет TMyInterface.Create(), а не IMyInterface.Create();) –

3

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

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