Delphi的内存管理及内存泄露问题 FastMM4
这几天因为一个程序长时间运行出现比较严重的内存泄露问题,开始关注了一下内存管理方面的东西,以前也注意内存管理,创建了对象及时释放,但总有忘了处理的情况。
在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.检查泄漏后要自己去检查代码补齐内存释放,报告并不能做这事
Delphi的内存管理及内存泄露问题 FastMM4的更多相关文章
- SAP专家培训之Netweaver ABAP内存管理和内存调优最佳实践
		
培训者:SAP成都研究院开发人员Jerry Wang 1. Understanding Memory Objects in ABAP Note1: DATA itab WITH HEADER LINE ...
 - Android 之 内存管理-查看内存泄露(三)
		
概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...
 - Java的内存管理与内存泄露
		
作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端.服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存 ...
 - [C]内存管理、内存泄露、堆栈
		
原文地址:https://www.cnblogs.com/youthshouting/p/4280543.html,转载请注明源地址. 1.内存分配区间: 对于一个C语言程序而言,内存 ...
 - 浅谈C语言内存管理、内存泄露、堆栈
		
1.内存分配区间: 对于一个C语言程序而言,内存空间主要由五个部分组成:代码段(.text).数据段(.data).静态区(.BSS).堆和栈组成. BSS段:BSS段 ...
 - Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)
		
专题:Linux内存管理专题 关键词:slub_debug.kmemleak.kasan.oob.Redzone.Padding. Linux常见的内存访问错误有: 越界访问(out of bound ...
 - Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)【转】
		
转自:https://www.cnblogs.com/arnoldlu/p/8568090.html 专题:Linux内存管理专题 关键词:slub_debug.kmemleak.kasan.oob. ...
 - Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)
		
勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇分享了JVM及其启动流程,今天介绍一下JVM内部的一些区域,以及具体的区域在运行 ...
 - davlik虚拟机内存管理之一——内存分配
		
转载自http://www.miui.com/thread-74715-1-1.html dalvik虚拟机是Google在Android平台上的Java虚拟机的实现,内存管理是dalvik虚拟机中的 ...
 
随机推荐
- OpenJudge计算概论-矩阵归零消减序列和
			
矩阵归零消减序列和 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个n*n的矩阵( <= n <= ,元素的值都是非负整数).通过n-1次实施下述过程,可把这个矩阵转 ...
 - CentOS 6使用mutt+msmtp发送邮件
			
转:http://www.tuicool.com/articles/YRnQVfq CentOS系统下如果希望向外域发送邮件,需要配置sendmail+dovecot等一系列工具.其实不用这么麻烦,只 ...
 - Hadoop 源码编译导出
			
https://svn.apache.org/repos/asf/hadoop/common/branches/branch-trunk-win/BUILDING.txt http://www.src ...
 - Visual对象之DrawingContext.DrawRectangle在有的状态下似乎并不能提高性能
			
很多书上都提到使用Visual对象绘制图形可以提高绘图效率,但是经过本人亲测,结果却发现DrawingContext.DrawRectangle的效率远低于使用UIElement.Children.A ...
 - Avant Browser
			
Avant Browser Avant 浏览器友好的用户界面为你的网络冲浪带来全新的效率和透明性.软件版本的不断升级使产品的可靠性稳步提高. 没有广告.没有恶意软件! Avant 浏览器是免费的.10 ...
 - sublime text 3  安装注释
			
sublime text 3 1.安装Sublime Text 3 下载安装:http://www.sublimetext.com/3 Package Control安装:https://subli ...
 - SDS查看部署在集成TOMCAT服务器中的项目目录结构
 - HashMap的实现
			
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
 - Maven使用--打包和运行
			
将项目进行编译.测试后,下一个重要步骤就是打包.简单执行命令mvn clean package进行打包.Maven会在打包前执行编译.测试等操作. 在打包后,执行安装任务install ...
 - [Android-2A] -仿IOS微信滑动删除_SwipeListview左滑删除例子
			
https://yunpan.cn/cueUIQkRafQrH (提取码:7ec1) 关于这样类似的例子网上的代码很多,最近发现这个例子里的代码在开发中会遇到一系列的问题.比如ListView的OnI ...