Delphi ใช้ Concept Manual Memory Management ในการจัดการ Win32 และ Win64 Application
.Create (constructor) ต้องถูกทำลายด้วย .Free.Free จะเรียก .Destroy (destructor) ให้โดยอัตโนมัติหากเราวาง Component บน TForm หรือ TDataModule เราไม่จำเป็นจะต้องสนใจเรื่องการ Free Component เนื่องจากเมื่อ Component ถูกกำหนด Owner ให้เป็นตัว Form หรือ DataModule จะส่งผลให้ Component เหล่านั้นถูก Free ไปพร้อมๆกับ Form หรือ DataModule
var MyButton1 := TButton.Create(Application); // MyButton1 จะถูก Free ไปพร้อมๆกับ Application
var MyButton2 := TButton.Create(Self); // MyButton จะถูก Free ไปพร้อมๆกับ Self (TForm, TDataModule)
var MyButton3 := TButton.Create(Form1); // MyButton จะถูก Free ไปพร้อมๆกับ Form1
begin
var List := TStringList.Create;
List.Add('Hello Delphi');
List.Add('Memory Management');
List.Free;
end;
โค้ดนี้ดูเหมือนจะถูกต้องแต่ถ้าเกิด Exception กับสเตทเม้นใดก่อนถึง
.Freeจะเกิด Memory Leak ทันที เนื่องจาก.Freeจะไม่ถูก Execute ซึ่งวิธีแก้ก็คือtry...finally
try...finallytry...finally ถูกออกแบบมาเพื่อ รับประกันว่าทรัพยากรจะถูกคืนกลับเสมอ ไม่ว่าโค้ดจะเกิด Exception หรือไม่ก็ตาม
begin
var List := TStringList.Create;
try
List.Add('Hello Delphi');
List.Add('Memory Management');
finally
List.Free;
end;
end;
trytryFree อยู่ใน finally เท่านั้นสเตทเม้นใน
finallyจะถูกเรียกเสมอ ไม่ว่าโค้ดจะเกิด Exception หรือไม่ก็ตามแต่สเตทเม้นใน
finallyจะไม่ถูก Execute ในกรณีที่var List := TStringList.Create;เกิด Exception ซึ่งจะทำให้ไม่เกิดปัญหา Access Violation
try...finally จัดการ Object มากกว่า 1 ตัวbegin
var sl1 := TStringList.Create;
try // try...finally sl1
sl1.Add('Hello Delphi');
var sl2 := TStringList.Create;
try // try...finally sl2
sl2.Add(sl1.Text);
finally
sl2.Free;
end;
finally
sl1.Free;
end;
end;
begin
try
var List := TStringList.Create;
List.Add('Hello Delphi');
List.Add('Memory Management');
finally
List.Free;
end;
end;
ในกรณีที่
var List := TStringList.Create;เกิด Exception จะส่งผลให้Listมีค่าเป็นnilทำให้.Freeเกิดปัญหา Access Violation
หลายคนสับสนว่า try...except กับ try...finally มีการนำไปไปใช้แตกต่างกันอย่างไร
try...except → จัดการ Errortry...finally → จัดการ Resourcebegin
var FileStream := TFileStream.Create('data.txt', fmOpenRead);
try // try...finally
try // try...except
ProcessFile(FileStream);
except
on E: Exception do
begin
ShowMessage('เกิดข้อผิดพลาด: ' + E.Message);
end;
end;
finally
FileStream.Free;
end;
end;
exceptfinally เสมอไม่ว่าจะเกิด Exception หรือไม่ก็ตาม.Create ต้องถูกทำลายด้วย .Free.Free จะเรียก .Destroy ให้โดยอัตโนมัติ