Сборка мусора в Дельфах - PullRequest
17 голосов
/ 14 декабря 2010

Есть ли у Delphi Garbage Collection?

Ответы [ 6 ]

24 голосов
/ 14 декабря 2010

Простой ответ №

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

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

19 голосов
/ 14 декабря 2010

Да, это так.

Delphi Win32 не включает сборщик мусора из коробки , поэтому другие ответы на этот вопрос технически верны.Тем не менее, это не означает, что это невозможно или что он еще не существует.Благодаря заменяемому диспетчеру памяти Delphi Барри Келли внедрил полностью функциональную оболочку для Boehm сборщика мусора еще в 2004 году.

Включает пример кодадемонстрация его использования (в основном создание неназначенных объектов и наблюдение за тем, как GC их разжевывает).Существуют более продвинутые GC, чем Boehm GC, но это наглядно демонстрирует их возможность и может использоваться почти прозрачно.Вы просто добавляете модуль gc в начало предложения использования вашего проекта.

И хотя я не слышал ни о каких проектах, пытающихся это сделать, ничто не мешает кому-то обернуть или перенести более продвинутый gc.

7 голосов
/ 14 декабря 2010

В обычном смысле сборки мусора, когда среда выполнения обнаруживает не связанные объекты и уничтожает их или иным образом возвращает неиспользуемые ресурсы, нет, Delphi не имеет сборки мусора.

Если вы используете нативный Win32 Delphi, тогдаНаиболее близким к сборке мусора являются различные типы с подсчетом ссылок, включая строки, интерфейсы, варианты и динамические массивы.Эти типы будут очищены автоматически, когда ваша программа определит, что они больше не используются, но делает это, сохраняя счетчик ссылок, когда эти объекты входят и выходят из текущей области.У вас также есть концепция владение , которая будет уничтожать принадлежащие компоненты при уничтожении владельца.

Если вы используете Delphi для .Net, то у вас неявно будет сборка мусора базовой среды выполнения..

2 голосов
/ 18 декабря 2010

Delphi-Prism

имеет сборщик мусора, так как он основан на .NET

Стандартный Delphi (собственный Win32)

Не имеет сборки мусора

1 голос
/ 21 мая 2017

Delphi Win32 / 64 не имеет сборщика мусора.Однако вы можете воспользоваться механизмом подсчета ссылок Delphi для автоматического освобождения экземпляров с помощью интерфейсов.

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

0 голосов
/ 26 октября 2018

Да!Посмотрите на этот класс

unit uGC;

interface

uses
  System.Generics.Collections, Rtti, System.Classes;

type
  TGarbageCollector = class(TComponent)
  public
    const
      DEFAULT_TAG = 'DEFAULT_TAG';
  private
    items: TDictionary<TObject, string>;
  public
    destructor Destroy; override;
    constructor Create(AOwner: TComponent); override;
    function Add<T>(item: T): T; overload;  
    function Add<T>(item: T; const tag: string): T; overload;  
    procedure Collect(const tag: string);
  end;

var
  GC: TGarbageCollector;

implementation

uses
  System.Types, System.SysUtils;


constructor TGarbageCollector.Create(AOwner: TComponent);
begin
  inherited;
  items := TObjectDictionary<TObject, string>.Create([doOwnsKeys]);
end;

destructor TGarbageCollector.Destroy;
begin
  items.free();
  inherited Destroy;
end;

function TGarbageCollector.Add<T>(item: T): T;
begin
  result := Add(item, DEFAULT_TAG);
end;

function TGarbageCollector.Add<T>(item: T; const tag: string): T;
var
  obj: TObject;
  v: TValue;
begin
  v := TValue.From<T>(item);
  if v.IsObject then
  begin
    items.add(v.AsObject, tag);
    result := item;
  end
  else
    raise Exception.Create('not an Object');
end;

procedure TGarbageCollector.Collect(const tag: string);
var
  key: TObject;
  item: TPair<TObject, string>;
  gcList: TList<TObject>;
begin
  gcList := TList<TObject>.Create();
  try
    for item in items do
    begin
      if (item.Value = tag) then
        gcList.add(item.Key);
    end;

    for key in gcList do
      items.remove(key);
  finally
    gcList.free();
  end;
end;

end.

Создайте его так

program GarbageCollector;

uses
  Vcl.Forms,
  uMain in 'uMain.pas' {Main},
  uGC in 'uGC.pas',
  uSomeClass in 'uSomeClass.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  GC := TGarbageCollector.Create(Application); // <<<
  Application.CreateForm(TMain, Main);
  Application.Run;
end.

Используйте вот так

  someInstance := GC.Add(TSomeClass.Create(nil), 'TSomeClassTag');
  // do smth with someInstance
  //now destroy
  GC.Collect('TSomeClassTag');
  //
  anotherInstance := GC.Add(TSomeClass.Create(nil), 'TSomeClassTag');
  // do smth with anotherInstance
  // not destroying here - will be destroyed on app destroy...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...