zoukankan      html  css  js  c++  java
  • 了解和防止内存泄露

    支持面向对象编程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

  • 相关阅读:
    环形二维数组
    梦断代码(三)
    梦断代码(二)
    梦断代码(一)
    CNblogs用户体验
    《软件工程》--读书笔记三
    《软件工程》--读书笔记二
    《软件工程》--读书笔记一
    找出水王
    典型用户
  • 原文地址:https://www.cnblogs.com/findumars/p/4998949.html
Copyright © 2011-2022 走看看