这几天因为一个程序长时间运行出现比较严重的内存泄露问题,开始关注了一下内存管理方面的东西,以前也注意内存管理,创建了对象及时释放,但总有忘了处理的情况。

在Delphi中没有自动回收机制,所以一定要及时释放使用的内存,虽然有时小的内存泄露并不会造成太大的问题。

Delphi中检测内存泄露可以使用开源的FastMM(http://sourceforge.net/projects/fastmm/),使用很简单,在工程的第一行引用FastMM4即可(注意,一定要在第一个Uses的位置),可以在调试程序时提示内存泄露情况,还可以生成报告。

在Delphi2010中,使用更加简单,只需要在工程开始的位置加上语句:

ReportMemoryLeaksOnShutdown := DebugHook<>0;

就可以了,并且在运行时不会出现提示。如果想要生成文件报告,还需要FastMM4,Delphi2010中或许有别的设置可以生成文件报告,没有找到。

可以修改FastMM4Options.inc中的参数开关来修改内存管理的相关设置。

后来在网上又发现了一个说是让Delphi支持自动垃圾回收的东东,很高兴,看了一下:

http://www.hpl.hp.com/personal/Hans_Boehm/gc/

有编译好的,可以支持多种开发语言,也可以支持Delphi,于是测试了一下,发现这个程序好像只是在系统退出时进行垃圾回收,比如你有两个窗体,form1和form2,form1调用form2,而form2中创建了一个对象没有释放,则在你注销form2的时候form2中使用的对象的内存并没有释放,而是要等到程序结束,所以这种垃圾回收时机有点晚了,如果你程序有大的内存泄露会导至系统内存问题的话,这个程序并不会帮你解决这个问题。(没有详细测试,哪位大侠有经验可以指点指点  :-)   )

所以,最好的办法还是你自己在写程序的时候一定要注意释放掉使用的内存,可以借助fastmm来帮你找可能的内存泄露。

附:FastMM的使用(转自网络)

使用说明如下:    
  1.打开FastMM4的调试功能,首先在自己的project里把FastMM4放在最前面,例如:  
      FastMM4,  
      Main   in   ‘Main.pas’   {MainForm},  
   
  再修改FastMM4Options.inc,打开全调试模式。例:  
  {$define   FullDebugMode}  
  也可以在project中定义编译常量:FullDebugMode。同时把FastMM_FullDebugMode.dll拷贝到编译后生成的可执行程序所在目录。  
  再要打开内存泄漏报告:EnableMemoryLeakReporting。一般情况下是缺省打开的。  
  这样就打开了全调试模式,如果发生内存泄漏将会生成报告文件,如果在IDE运行的时候还会弹出一个对话框显示。报告文件类似:XXX_MemoryManager_EventLog.txt  
   
  2.报告文件由两部分组成,并且是每次运行append。  
   
  第一部分是泄漏的详细内容,将每个没释放的内存块详细信息显示出来。例:  
  A   memory   block   has   been   leaked.   The   size   is:   28       {一个28字节的内存块在程序结束后没有被释放}  
   
  {这个内存块在分配的时候的调用堆栈,也就是Call   Stack,可以清楚看出调用函数的次序。如果是系统dll则还有相应的函数名。}  
  Stack   trace   of   when   this   block   was   allocated   (return   addresses):  
  4028E7  
  4030EC  
  406649  
  412365  
  41236E  
  411DD3  
  426B45  
  427236  
  42888C  
  {这个内存类型,如果是字符串string或TObject继承的对象则会显示名称及行号。}  
  The   block   is   currently   used   for   an   object   of   class:   Unknown  
  {将内存块头256个字符显示出现,作为内容提示。}  
  Current   memory   dump   of   256   bytes   starting   at   pointer   address   107BDD8:  
   
  第二部分是总结性内容,例:  
   
  {这个小型内存块泄漏的报告,如果有大型内存块泄漏则会加一行专门提示大型内存块泄漏。}  
  This   application   has   leaked   memory.   The   small   block   leaks   are   (excluding   expected   leaks   registered   by   pointer):  
   
  {21-28字节的内存块泄漏,未知类型一个}  
  21   -   28   bytes:   Unknown   x   1  
   
  Note:   Memory   leak   detail   is   logged   to   a   text   file   in   the   same   folder   as   this   application.   To   disable   this   memory   leak   check,   undefine   “EnableMemoryLeakReporting”.    
   
  有了这份报告只不过了解到内存泄漏存在,但是哪里没释放就还需要更进一步地调查。  
   
  调查的目标有:  
   
  1.内存块分配在哪个函数里哪段代码。  
   
  这个在报告里可以结合内容和调用堆栈来看。前256个字节可以进行分析,推测分配者,调用堆栈就直接指出了分配函数,不过是一些地址,不能直接知道函数名和代码段。这时候就需要在delphi   ide环境下查看二进制内存映像了,就是View   CPU功能。  
   
  在设定断点并停下后,可以View   CPU,在菜单View=>Debug   Window=>CPU     快捷键:Ctrl+Alt+C  
   
  View   CPU   Window:      
   
  正中就是内存映像,而且源码也相应地标注好了,左边列的地址就是内存报告中的Call   Stack中的地址,翻页找到所对应的代码就知道哪里分配内存了。  
   
  2.检查释放内存的地方是否被调用,可以用日志或断点来调试,如果压根就没有释放内存那就补上代码,如果有却没有执行则检查一下执行条件是否正确,如果断点没起作用很可能是因为代码永远不会被执行(死代码)。  
   
  这要靠经验和调试,基本上借助IDE和内存报告就可以很好地防止内存泄漏。同时要加强测试用例,争取在测试用例中能遍历到所有的代码和大部分关键功能,这样内存泄漏报告就会更准确一点。  
   
  fastmm每次在程序关闭后就会根据情况生成内存泄漏报告,如果没有弹出内存泄漏警告则恭喜你,内存管得很好。  
   
  另:  
   
  1.内存管理不是GC自动回收内存,而是检查是否有泄漏。  
   
  2.windows系统的内存泄漏是无法检查的,仅限于应用程序内部,不过检查出系统泄漏也没办法,只能等更新了。  
   
  3.检查泄漏后要自己去检查代码补齐内存释放,报告并不能做这事。

I'd like morning better if they started later !

----garfield

转载于:https://www.cnblogs.com/GarfieldTom/archive/2009/12/09/1619876.html

Delphi的内存管理及内存泄露问题相关推荐

  1. C++ 内存管理中内存泄漏问题产生原因以及解决方法

    C++内存管理中内存泄露(memory leak)一般指的是程序在申请内存后,无法释放已经申请的内存空间,内存泄露的积累往往会导致内存溢出. 一.内存分配方式 通常内存分配方式有以下三种: (1)从静 ...

  2. 【Linux 内核 内存管理】内存管理架构 ④ ( 内存分配系统调用过程 | 用户层 malloc free | 系统调用层 brk mmap | 内核层 kmalloc | 内存管理流程 )

    文章目录 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) 二.内存管理流程 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) " 堆内存 " ...

  3. SAP专家培训之Netweaver ABAP内存管理和内存调优实践

    培训者:SAP成都研究院开发人员Jerry Wang 1. Understanding Memory Objects in ABAP Note1: DATA itab WITH HEADER LINE ...

  4. Linux内存管理之内存管理单元(MMU)(二)

    Linux内存管理之内存管理单元(二) 1.1.什么是MMU 在CPU内部,有一个专门的硬件单元来负责这个虚拟页面到物理页面的转换,它被被称为内存管理单元(Memory Management Unit ...

  5. Linux内存管理:内存寻址之分段机制与分页机制

    目录 Linux 内存寻址之分段机制 前言 分段到底是怎么回事? 实模式的诞生(16位处理器及寻址) 保护模式的诞生(32位处理器及寻址) IA32的内存寻址机制 寻址硬件 IA32的三种地址 MMU ...

  6. Linux内存管理:内存分配:slab分配器

    <linux内核之slob.slab.slub> <Linux内核:kmalloc()和SLOB.SLAB.SLUB内存分配器> <Linux内存管理:内存分配:slab ...

  7. Linux内存管理:内存描述之高端内存

    <Linux内存管理:内存描述之内存节点node> <Linux内存管理:内存描述之内存区域zone> <Linux内存管理:内存描述之内存页面page> < ...

  8. Linux内存管理:内存描述之内存页面page

    <Linux内存管理:内存描述之内存节点node> <Linux内存管理:内存描述之内存区域zone> <Linux内存管理:内存描述之内存页面page> 目录 1 ...

  9. Linux内存管理:内存描述之内存节点node

    <Linux内存管理:内存描述之内存区域zone> <Linux内存管理:内存描述之内存节点node> 目录 1 前景回顾 1.1 UMA和NUMA两种模型 1.2 (N)UM ...

  10. 【Linux 内核 内存管理】内存映射相关数据结构 ③ ( vm_area_struct 结构体成员分析 | shared 成员 | anon_vma_chain 成员 | anon_vma 成员 )

    文章目录 一.vm_area_struct 结构体成员分析 1.shared 成员 2.anon_vma_chain 成员 3.anon_vma 成员 二.vm_area_struct 结构体完整源码 ...

最新文章

  1. linux7内核优化,centos7 系统内核、网络等优化(适用高并发)
  2. 并行计算框架 Apache Hama
  3. CSS的Grid网格布局
  4. iPhone7总不在服务区?免费网络电话可解通话烦恼
  5. Windows服务的创建、安装、调试
  6. java mapfile_基于文件的数据结构:关于MapFile
  7. python 保存文件 吃内存_孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化...
  8. 【SOLIDWORKS-详细记录】解决默认模板无效问题及添加自定义模板
  9. 网络安全学习第14篇 - 游戏(仙剑奇侠传95)外挂之修改游戏资源文件(修改人物属性)
  10. 模拟cmos集成电路设计之共源共栅电流镜
  11. 【Three.js】十二、three.js摄像机控件
  12. uniapp实现加载图片失败显示占位图
  13. oracle缩小数据文件大小,怎样将数据文件的大小变小
  14. win10安装mmcv和mmcv-full报错
  15. [原创].NET中防止Access数据库下载
  16. python安装第三方库re_音频处理 windows10下python三方库librosa安装教程
  17. 【设计模式学习笔记】类图:类与类之间的关系
  18. 【校招面经】阿里巴巴_数据分析岗_面试笔试题
  19. 质量管理之代码的圈复杂度
  20. C#程序下扫描枪扫描文本自动执行解决方案

热门文章

  1. MongoDB 入门篇
  2. 翻译 | 摆脱浏览器限制的JavaScript
  3. 使用 MTR 诊断网络问题
  4. Google Map App 问题集锦
  5. 今天感觉有点冷了其实。
  6. Oracle全文检索示例
  7. 圣诞节玩购目的地大比拼
  8. lvs十种调度策略+三种模式
  9. 《中国人工智能学会通讯》——10.22 能源互联网时代
  10. [UWP]用Shape做动画(2):使用与扩展PointAnimation