ImageVerifierCode 换一换
格式:DOCX , 页数:14 ,大小:82.53KB ,
资源ID:7289466      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7289466.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(FastMM参考资料.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

FastMM参考资料.docx

1、FastMM参考资料FastMM、FastCode、FastMove的使用FastMM是一个替换Embarcadero Delphi Win32应用程序的快速内存管理器,以及可以在多线程下使用,不容易产生内存碎片,并且无需使用外部DLL文件就可以支持共享内存。使用方法:1.对IDE加速 解压之后,文件夹./FastMM/Replacement BorlndMM DLL/Delphi/Precompiled/for Delphi IDE/Performance下的BorlndMM.dll拷贝到Delphi安装目录下的./Borland/Delphi7/Bin进行覆盖安装(最好先备份下)。2.对应

2、用程序加速 打开Delphi IDE,将文件夹./FastMM添加到Environment Options下的Library中。然后再在具体项目工程中,在菜单栏ProjectView Source下,将FastMM4.pas单元添加到uses下的第一个位置。若需要内存报告消息为中文的话,将文件./FastMM/Translations/Chinese (Simplified)/FastMM4Messages.pas替换文件./FastMM/FastMM4Messages.pas即可。下面测试内存泄露报告:1)新建一个Delphi应用程序,在工程文件将FastMM4.pas单元添加到uses下的

3、第一个位置;2)添加一个按钮,按钮单击事件如下:123456procedureTForm1.btn1Click(Sender:TObject);varsl:TStrings;beginsl:=TStringList.Create;end;3)运行程序,单击按钮,退出程序,观察结果如下图所示: 从上面可以看到有报告内存泄露,并且提示TStringList.泄露,提醒要得到详细的内存泄露信息,需开启FullDebugMode和LogMemoryLeakDetailToFile条件编译开关。打开文件./FastMM/FastMM4Options.inc,在文件末尾添加以下代码:快速配置发布版本和调试

4、版本$ifdefRelease发布版本请设置$undefFullDebugMode$undefCheckHeapForCorruption$defineASMVersion$undefEnableMemoryLeakReporting$undefUseOutputDebugString$else调试版本请设置$defineFullDebugMode$defineEnableMemoryLeakReporting$defineUseOutputDebugString$endif再将文件./FastMM/FullDebugMode DLL/Precompiled/FastMM_FullDebugM

5、ode.dll拷贝到工程可执行程序目录下,运行程序,单击按钮,观察结果如下图所示:在工程目录下有日志文件Project1_MemoryManager_EventLog.txt记录内存泄露详细信息,如下图所示:若是发布版本的话,关闭调试模式,在菜单栏ProjectOptionsDirectories/ConditionalsConditionals下,定义一个条件编译Release,如下图所示:再次运行程序,单击按钮,观察结果,已经无内存泄露报告提示框了。注意以上仅在IDE中调试程序有检查内存泄露,若是要在脱离IDE运行程序也检测内存泄露,请关闭选项 $define RequireDebugge

6、rPresenceForLeakReporting,此项默认开启。FastCode为Delphi社区提供高度优化的函数,此函数比Delphi运行时库函数、VCL函数以及它们的扩展函数更快。FastMove替换所有的system.move调用,因为它有更快的速度。使用方法: 解压之后,将FastMove放到FastCode文件夹下,这样就只需引用一个环境路径,将./FastCode添加到Environment Options下的Library中。然后再在具体项目工程中,在菜单栏ProjectView Source下,将FastCode.pas和FastMove.pas单元添加到uses下的第一个

7、位置,如下所示:01020304050607080910111213141516programProject1;usesFastMM4,假如有FastMM的话,放在第一个位置FastCode,FastMove,Forms,Unit1inUnit1.pasForm1;$R*.resbeginApplication.Initialize;Application.CreateForm(TForm1,Form1);Application.Run;end. 若是FastMM和FastMove同时使用的话,需要禁用其中一个条件编译,打开文件./FastMM/FastMM4Options.inc,按Ctrl

8、+F寻找字符串$define UseCustomVariableSizeMoveRoutines,找到之后将此行改为如下:.$defineUseCustomVariableSizeMoveRoutines 使用FastMove代码可以使整个程序都使用到更快的内存移动函数而不仅仅是内存管理器。因此建议将FastMM和FastMove代码相结合,并关闭此选项。FastMM、FastCode、FastMove打包下载:扩展资料:1.Delphi中使用FastMM4结合View CPU避免内存泄漏2.FastMM使用详解FastMM使用详解一、引言 FastMM是适用于delphi的第三方内存管理器,

9、在国外已经是大名鼎鼎,在国内也有许多人在使用或者希望使用,就连Borland也在delphi2007抛弃了自己原有的饱受指责的内存管理器,改用FastMM. 但是,内存管理的复杂性以及缺乏FastMM中文文档导致国内许多人在使用时遇到了许多问题,一些人因此而放弃了使用,我在最近的一个项目中使用了FastMM,也因此遇到了许多问题,经过摸索和研究,终于解决了这些问题。二、为什么要用FastMM第一个原因是FastMM的性能接近与delphi缺省内存管理器的两倍,可以做一个简单的测试,运行下面的代码:varI: Integer;Tic: Cardinal;S: string;begintic :=

10、 GetTickCount;try for I := 0 to 100000 do begin SetLength(S, I + 100); edt1.Text := S; end;finally SetLength(S, 0); tic := GetTickCount - Tic; MessageDlg(Tic = + IntToStr(Tic), mtInformation, mbOK, 0);end;end;在我的IBM T23笔记本上,使用FastMM4(FastMM的最新版本)用时约为3300ms,而使用缺省的内存管理器,用时约为6200ms,FastMM4的性能提高达88%.第二个

11、原因FastMM的共享内存管理器功能使用简单可靠。当一个应用程序有多个模块(exe和dll)组成时,模块之间的动态内存变量如string的传递就是一个很大的问题,缺省情况下,各个模块都由自己的内存管理器,由一个内存管理器分配的内存也必须在这个内存管理器才能安全释放,否则就会出现内存错误,这样如果在一个模块分配的内存在另外一个模块释放就会出现内存错误。解决这个问题就需要使用到共享内存管理器,让各个模块都使用同一个内存管理器。Delphi缺省的共享内存管理器是BORLNDMM.DLL,这个内存管理器并不可靠,也常常出现问题,并且,在程序发布的时候必须连同这个DLL一起发布。而FastMM的共享内存

12、管理器功能不需要DLL支持,并且更加可靠。第三个原因是FastMM还拥有一些帮助程序开发的辅助功能,如内存泄漏检测功能,可以检测程序是否存在未正确释放的内存等。三、出现什么问题如果我们开发的应用程序,只有一个exe模块,那么,使用FastMM是一件非常简单的事情,只需要把FastMM.pas(最新版是FastMM4.pas)作为工程文件的第一个uses单元即可,如:program Test;uses FastMM4, 但是,通常情况下,我们的应用程序都是由一个exe模块加上多个dll组成的,这样,当我们跨模块传递动态内存变量如string变量时,就会出问题,比如,下面的测试程序由一个exe和一

13、个dll组成:library test; / test.dlluses FastMM4, ;procedure GetStr(var S: string; const Len: Integer); stdcall;begin SetLength(S, Len); /分配内存 FillChar(S1, Len, A); end;exports GetStr;-program TestPrj;uses FastMM4, ;/-unit mMain; /测试界面procedure TForm1.btnDoClick(Sender: TObject);varI: Integer;S: string;B

14、egintryfor I := 1 to 10000 dobegin GetStr(S, I + 1); edt1.Text := S; Application.ProcessMessages;end;finally SetLength(S, 0);end;end;当第二次执行btnDoClick过程时,就会出现内存错误,为什么这样?delphi的字符串是带引用计数的,跟接口变量一样,一旦这个引用计数为0,则会自动释放内存。在btnDoClick过程中,调用GetStr过程,用SetLength给S分配了一段内存,此时这个字符串的引用计数为1,然后执行edt1.Text := S语句,字符串的

15、引用计数为2,循环再调用GetStr给S重新分配内存,这样原来的字符串的引用计数减1,再执行edt1.Text := S,原来的字符串引用计数为0,这时,就会被释放(注意,是在TestPrj.exe释放,而不是在Test.dll释放),但这时没有出错,当循环执行完毕之后,还有一个字符串的引用计数为2,但是执行SetLength(S, 0)之后,该字符串被edt1.Text引用,的引用计数为1,第二次执行btnDoClick时,执行edt1.Text := S时,上次的引用计数为1的字符串引用计数减一变为0,就会被释放,此时,会出现内存错误。由此,可以看到,在另一个模块释放别的模块分配的内存,并

16、不一定马上出现内存错误,但是,如果频繁执行,则会出现内存错误,这种不确定的错误带有很大的隐蔽性,常常在调试时不出现,但实际应用时出现,不仔细分析很难找到原因。要解决这个问题,就要从根源找起,这个根源就是内存管理。Delphi的内存管理,Delphi应用程序可以使用的有三种内存区:全局内存区、堆、栈,全局内存区存储全局变量、栈用来传递参数以及返回值,以及函数内的临时变量,这两种都是由编译器自动管理,而如字符串、对象、动态数组等都是从堆中分配的,内存管理就是指对堆内存管理,即从堆中分配内存和释放从堆中分配的内存(以下称内存的分配和释放)。我们知道,一个进程只有一个栈,因此,也很容易误以为一个进程也

17、只有一个堆,但实际上,一个进程除了拥有一个系统分配的默认堆(默认大小1MB),还可以创建多个用户堆,每个堆都有自己的句柄,delphi的内存管理所管理的正是自行创建的堆,delphi还把一个堆以链表的形式分成多个大小不等的块,实际的内存操作都是在这些块上。delphi把内存管理定义为内存的分配(Get)、释放(Free)和重新分配(Realloc)。内存管理器也就是这三种实现的一个组合,delphi在system单元中定义了这个内存管理器TMemoryManager:PMemoryManager = TMemoryManager;TMemoryManager = record GetMem:

18、function (Size: Integer): Pointer; FreeMem: function (P: Pointer): Integer; ReallocMem: function (P: Pointer; Size: Integer): Pointer;end;由此知道,delphi的内存管理器就是一个TMemoryManager记录对象,该记录有三个域,分别指向内存的分配、释放和重新分配例程。System单元还定义了一个变量MemoryManager:MemoryManager: TMemoryManager = ( GetMem: SysGetMem; FreeMem: Sy

19、sFreeMem; ReallocMem: SysReallocMem);该变量是delphi程序的内存管理器,缺省情况下,这个内存管理器的三个域分别指向GETMEM.INC中实现的SysGetMem、SysFreeMem、SysReallocMem。这个内存管理器变量只在system.pas中可见,但是system单元提供了三个可以访问该变量的例程:/读取内存管理器,也即读取MemoryManagerprocedure GetMemoryManager (var MemMgr: TMemoryManager);/安装内存管理器(即用新的内存管理器替换缺省的内存管理器)procedure Se

20、tMemoryManager (const MemMgr: TMemoryManager);/是否已经安装了内存管理器(即缺省的内存管理器是否已经被替换)function IsMemoryManagerSet: Boolean;四、共享内存管理器什么是共享内存管理器?所谓共享内存管理器,就是一个应用程序的所有的模块,不管是exe还是dll,都使用同一个内存管理器来管理内存,这样,内存的分配和释放都是同一个内存管理器完成的,就不会出现内存错误的问题。那么如何共享内存管理器呢?由上分析,我们可以知道,既然要使用同一个内存管理器,那么干脆就创建一个独立的内存管理器模块(dll),其他的所有模块都使用

21、这个模块的内存管理器来分配和释放内存。Delphi7默认就是采取这种方法,当我们使用向导创建一个dll工程时,工程文件会有这样一段话:Important note about DLL memory management: ShareMem must be thefirst unit in your librarys USES clause AND your projects (selectProject-View Source) USES clause if your DLL exports any procedures orfunctions that pass strings as par

22、ameters or function results. Thisapplies to all strings passed to and from your DLL-even those thatare nested in records and classes. ShareMem is the interface unit tothe BORLNDMM.DLL shared memory manager, which must be deployed alongwith your DLL. To avoid using BORLNDMM.DLL, pass string informati

23、onusing PChar or ShortString parameters. 这段话提示我们,ShareMem是BORLNDMM.DLL共享内存管理器的接口单元,我们来看看这个ShareMem,这个单元文件很简短,其中有这样的声明:constDelphiMM = borlndmm.dll;function SysGetMem (Size: Integer): Pointer;external DelphiMM name BorlndmmSysGetMem$qqri;function SysFreeMem(P: Pointer): Integer;external DelphiMM name

24、 BorlndmmSysFreeMem$qqrpv;function SysReallocMem(P: Pointer; Size: Integer): Pointer;external DelphiMM name BorlndmmSysReallocMem$qqrpvi;这些声明保证了BORLNDMM.DLL将被静态加载。在ShareMem的Initialization是这样的代码:if not IsMemoryManagerSet then InitMemoryManager;首先判断内存管理器是否已经被安装(也即是否默认的内存管理器被替换掉),如果没有,则初始化内存管理器,InitMem

25、oryManager也非常简单(把无用的代码去掉了):procedure InitMemoryManager;varSharedMemoryManager: TMemoryManager;MM: Integer;begin/ force a static reference to borlndmm.dll, so we dont have to LoadLibrarySharedMemoryManager.GetMem:= SysGetMem;MM: = GetModuleHandle (DelphiMM);SharedMemoryManager.GetMem:= GetProcAddress

26、 (MM,BorlndmmSysGetMem$qqri);SharedMemoryManager.FreeMem:= GetProcAddress (MM,BorlndmmSysFreeMem$qqrpv);SharedMemoryManager.ReallocMem:= GetProcAddress (MM, BorlndmmSysReallocMem$qqrpvi);SetMemoryManager (SharedMemoryManager);end;这个函数定义了一个内存管理器对象,并设置域指向Borlndmm.dll的三个函数实现,然后调用SetMemoryManager来替换默认的内

27、存管理器。这样,不管那个模块,因为都要将ShareMem作为工程的第一个uses单元,因此,每个模块的ShareMem的Initialization都是最先被执行的,也就是说,每个模块的内存管理器对象虽然不相同,但是,内存管理器的三个函数指针都是指向Borlndmm.dll的函数实现,因此,所有模块的内存分配和释放都是在Borlndmm.dll内部完成的,这样就不会出现跨模块释放内存导致错误的问题。那么,FastMM又是如何实现共享内存管理器呢?FastMM采取了一个原理上很简单的办法,就是创建一个内存管理器,然后将这个内存管理器的地址放到一个进程内所有模块都能读取到的位置,这样,其他模块在创

28、建内存管理器之前,先查查是否有别的模块已经把内存管理器放到这个位置,如果是则使用这个内存管理器,否则才创建一个新的内存管理器,并将地址放到这个位置,这样,这个进程的所有模块都使用一个内存管理器,实现了内存管理器的共享。而且,这个内存管理器并不确定是哪个模块创建的,所有的模块,只要将FastMM作为其工程文件的第一个uses单元,就有可能是这个内存管理器的创建者,关键是看其在应用程序的加载顺序,第一个被加载的模块将成为内存管理器的创建者。那么,FastMM具体是如何实现的呢?打开FastMM4.pas(FastMM的最新版本),还是看看其Initialization部分:Initialize a

29、ll the lookup tables, etc. for the memory managerInitializeMemoryManager;Has another MM been set, or has the Borland MM been used? If so, this file is not the first unit in the uses clause of the projects .dpr file.if CheckCanInstallMemoryManager thenbegin InstallMemoryManager;end;InitializeMemoryManager是初始化一些变量,完成之后就调用CheckCanInstallMemoryManager检测FastMM是否是作为工程的第一个uses单元,如果返回True,则调用InstallMemoryManager

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1