【发布时间】:2010-12-14 15:36:28
【问题描述】:
德尔福有Garbage Collection吗?
【问题讨论】:
德尔福有Garbage Collection吗?
【问题讨论】:
简单的答案。
Delphi 不是一个完整的垃圾回收语言,用户定义的类型应该手动分配和释放。它只提供了自动收集,对于一些内置类型,例如字符串、动态数组和接口,以便于使用。
但你可以在一定程度上使用使用引用计数进行垃圾收集的接口。
【讨论】:
是的,确实如此。
Delphi Win32 不包括垃圾收集器开箱即用,所以这个问题的其他答案在技术上是正确的。但是,这并不意味着它不可能或不存在。感谢 Delphi 的可替换内存管理器 Barry Kelly 早在 2004 年就为 Boehm garbage collector 实现了功能齐全的 wrapper。
它包含演示其用法的示例代码(基本上是创建未分配的对象并观察 GC 咀嚼它们)。有比 Boehm GC 更先进的 GC,但这清楚地证明了它的可能性,并且几乎可以透明地使用它。您只需将 gc 单元添加到项目的 uses 子句的开头即可。
虽然我没有听说过任何尝试它的项目,但没有什么能阻止有人封装或移植更高级的 gc。
【讨论】:
在通常意义上的垃圾回收中,运行时检测未引用的对象并销毁它们或以其他方式回收未使用的资源,不,Delphi 没有垃圾回收。
如果您使用本机 Win32 Delphi,那么最接近垃圾收集的是各种引用计数类型,包括字符串、接口、变体和动态数组。当您的程序确定它们不再被使用时,这些类型将被自动清理,但它通过在这些对象进入和离开当前范围时保持引用计数来做到这一点。您还有所有权的概念,当所有者被销毁时,它会销毁拥有的组件。
如果您使用 Delphi for .Net,那么您隐含地拥有底层运行时的垃圾收集。
【讨论】:
Kylix(作为 Linux RTL 和 CLX),Delphi.NET(主观:与 2007 年一样半生不熟)-已停产; Delphi 7(实际上不到十年)- EoL,但有活跃的继任者。看到不同? Delphi Schism 是完全不同的产品。那么,近期应该选择什么样的环境,避免被锁在里面呢?
德尔福棱镜
有垃圾收集,因为它基于 .NET
标准 Delphi(本机 Win32)
没有垃圾收集
【讨论】:
Delphi Win32/64 没有垃圾收集器。 但是,您可以利用 Delphi 本机引用计数机制通过使用接口自动释放实例。
垃圾收集器和引用计数机制的区别在于你必须处理循环引用,即如果 A 和 B 实例相互引用,你需要手动打破循环以释放 A 或 B。
【讨论】:
是的!看看这堂课
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...
【讨论】: