Подтвердить что ты не робот

Сбор мусора в Дельфи

Есть ли у Delphi Сборка мусора?

4b9b3361

Ответ 1

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

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

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

Ответ 2

Да, это так.

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

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

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

Ответ 3

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

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

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

Ответ 4

Дельфи-Призм

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

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

Нет коллекции мусора

Ответ 5

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

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

Ответ 6

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

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...