支持面向对象编程Delphi是如此丰富和强大。雷和对象允许模块化编程。除了更多的模块和更多复杂的组件外,同时也带了更多的迷惑和更多复杂的Bugs。
当用Delphi开发一个程序(几乎)总是那么的有趣,当你感觉整个世界都在反对你的这个局面下。
无论什么时候你需要创建一个对象你就得释放它所使用的内存。无疑此时try...finally...end语句块可以帮助你防止内存泄露;它会持续不断的监视你的代码的安全性。
当程序失去释放它所耗费的内存的能力的时候就会发生内存(或资源)泄露。重复的内存泄露会导致一个进程无限制的使用内存。内存泄露是一个严重的问题--如你有个运行一周7天24小时的程序里一段代码引起内存泄露,那么程序将吃光所有可用的内存,最后会使机器停止反应。
Delphi的内存泄露
首先要阻止内存泄露就必须了解它们是如何出现的。下列所述将讨论一些常见的误区以及写没有内存泄露的Delphi代码的练习。
大多是情况下,(简单的)Delphi程序,你使用组件(Buttons, Memos, Edits等)拖放到一个窗体上(在设计期),不用太多的担心内存管理。一旦组件被拖放到窗体上,那么窗体就会成为它的所有者并且当窗体关闭(销毁)时将释放该组件的内存。窗体,作为一个拥有者,会为组件所拥有的内存负责。简单地说:窗体上的组件会自动创建和销毁。
一个简单的内存泄露示例
不论如何,在任何一个不繁琐的Delphi程序里,你需要实例化Delphi组件在运行期。你会实例化一些你自己编写的类。比如说你有一个类TDeveloper,它有一个方法DoProgram。现在,当要使用TDeveloper类时,你会通过调用Create方法(构造器)来实例化它。Create方法会给这个新对象分配内存并且返回这个对象的引用。
var
zarko: TDeveloper
begin
zarko := TMyObject.Create;
zarko.DoProgram;
end;
这儿就有一个简单的内存泄露
不论什么时候你创建一个对象,你就必须释放它所占用的内存。要释放分配给一个对象的内存,你就必须调用Free方法,非常肯定地说,你也会用try...finally...end语句块。
var
zarko : TDeveloper
begin
zarko := TMyObject.Create;
try
zarko.DoProgram;
finally
zarko.Free;
end;
end;
这是一个安全分配内存和重新分配的代码。
注意:如果你想动态实例化一个Delphi组件并且是在使用完后释放,总是传递nil作为拥有者。不这样做会带来不必要的风险,也会给性能和代码维护带来麻烦。请继续阅读本文。
一个简单的资源泄露示例
与使用Create和Free方法来创建和释放对象相比,你也必须非常小心的使用“外部”(文件,数据库等)。
比如说你需要操作一些文本文件。一个非常简单的做法:AssignFile方法是一个文件变量关联一个磁盘上的文件,当你使用完该文件之后,你必须调用CloseFile函数释放掉之前使用的文件句柄。这只是你没明确的调用“Free”。
var
F: TextFile;
S: string;
begin
AssignFile(F, 'c:somefile.txt') ;
try
Readln(F, S) ;
finally
CloseFile(F) ;
end;
end;
另外一个例子在你的代码里加载外部的DLLs,无论如何你用LoadLibrary,就必须调用FreeLibrary。
var
dllHandle : THandle;
begin
dllHandle := Loadlibrary('MyLibrary.DLL');
//do something with this DLL
if dllHandle <> 0 then
FreeLibrary(dllHandle);
end;
.NET中的内存泄露?
尽管Delphi for .NET中的garbage collector(GC)管理着大部分的内存任务,但是内存泄露在.NET程序中也是不无可能的。这里有一篇文章在讨论Delphi for .NET中的GC。(译者注:文章地址:http://delphi.about.com/od/delphifornet/a/aa060104a.htm)
如何抵抗内存泄露:
除了编写安全的内存代码模块外,防止内存泄露可以使用一些有效的第三方工具。Delphi内存泄漏的修复工具可以帮助你捕捉程序错误比如内存污染、内存泄露、内存分配错误、变量初始化错误、变量定义冲突、指针错误等等。
最后,自从我与Murphy一起开始,我会以同样的思维完成:
如果有人抱怨你的程序有一个内存泄露的问题,简单的回答他:
“这不是Bug, 只是文档中没有提到这个功能” :))
原文地址:http://delphi.about.com/od/oopindelphi/a/memoryleak.htm
http://www.lsworks.net/article/63.html