常见内存管理技术有哪些?已知三类,是否存在其他技术?
Delphi 内存管理技术补充
你已经了解的三种内存管理技术如下:
1. 手动管理
uses System.Classes; procedure DoSomething; var sl: TStringList; begin sl := TStringList.Create; try finally sl.Free; // 调用析构函数 end; end;
2. 引用计数/接口(TInterfacedObject)
标准库中最具代表性的示例:
uses Xml.XMLDoc, Xml.XMLIntf; procedure DoSomething; var xmldoc: IXMLDocument; begin xmldoc := TXMLDocument.Create(nil) as IXMLDocument; end; // 不再引用xmldoc,自动释放
3. 所有权机制
几乎整个VCL库都采用这种机制,示例如下:
uses System.Generics.Collections; procedure DoSomething; var ol: TObjectList<TObject>; i: Integer; o: TObject; begin ol := TObjectList<TObject>.Create(true); // 列表拥有对象所有权 try for i := 0 to 9 do begin o := TObject.Create; ol.Add(o); end; finally ol.Free; // 不仅释放列表,还会释放列表中的所有对象 end; end;
除此之外,还有以下几种内存管理技术:
自动引用计数(ARC)
从Delphi 10 Seattle开始,移动平台(iOS/Android)默认启用ARC,桌面平台也可手动开启。ARC会自动跟踪对象的引用数量,当引用计数归零时自动释放对象,无需手动调用Free或依赖接口。示例:// 启用ARC的项目中 procedure DoSomething; var obj: TObject; begin obj := TObject.Create; // 使用obj end; // obj超出作用域后自动释放栈分配值类型
对于不含引用类型成员的记录(record),会直接在栈上分配内存,超出作用域时自动销毁,无需手动管理。如果需要初始化和清理逻辑,可以配合初始化/终结方法:type TMyRecord = record Value: Integer; procedure Initialize; procedure Finalize; end; procedure TMyRecord.Initialize; begin Value := 0; end; procedure TMyRecord.Finalize; begin // 清理资源 end; procedure DoSomething; var rec: TMyRecord; begin rec.Initialize; try rec.Value := 10; finally rec.Finalize; end; end;内存池技术
针对频繁创建销毁的小对象,内存池可以减少内存碎片、提升分配释放效率。Delphi的System.MemoryPools单元提供了原生内存池支持,也可以自定义实现:uses System.MemoryPools; var Pool: IMemoryPool; procedure InitializePool; begin Pool := TMemoryPoolManager.DefaultPool; end; procedure DoSomething; var ObjPtr: Pointer; begin ObjPtr := Pool.Alloc(SizeOf(TObject)); try // 使用内存块 finally Pool.Free(ObjPtr); end; end;自定义智能指针
虽然Delphi原生没有C++风格的智能指针,但可以通过自定义类模拟独占或共享所有权的智能指针,在类析构时自动释放封装的对象:type TUniquePtr<T: class> = class private FObj: T; public constructor Create(AObj: T); destructor Destroy; override; function Get: T; inline; property Obj: T read Get; end; constructor TUniquePtr<T>.Create(AObj: T); begin inherited Create; FObj := AObj; end; destructor TUniquePtr<T>.Destroy; begin FObj.Free; inherited; end; function TUniquePtr<T>.Get: T; begin Result := FObj; end; // 使用示例 procedure DoSomething; var Ptr: TUniquePtr<TStringList>; begin Ptr := TUniquePtr<TStringList>.Create(TStringList.Create); Ptr.Obj.Add('Test'); end; // Ptr销毁时自动释放TStringList
内容的提问来源于stack exchange,提问作者complete_stranger
相关产品推荐
相关产品推荐

