FastMM相关

1.使用了FullDebugMod后,不显示行号?

  要显示行号需要在delphi中勾上"Debug Information","Reference Info" "Use Debug DCUs"

2.使用borlndmm.dll替换了IDE自带的以后,双开IDE然后关闭其中一个时会报错

  编译DLL时要设置“NeverUninstall”

3.使用了FullDebugMode后,报$808080xxx访问违例的错误

  通常是使用指针访问了已经释放的内存,FastMM会将已经释放的内存使用$80填充

4.使用了FastMM的内存泄漏检测会使应用程序运行变慢吗?

  不会,内存泄漏检测是在应用程序关闭时进行的


默认情况下FastMM调用栈的追踪深度是11,有时候可能不够用,可以在FastMM.pas中修改StackTraceDepth的值(注意注释:修改的值需要是奇数)


== FastMM技术细节

FastMM实际上是一个3合1的内存管理,分别是小块(<2.5k)、中块(<260k)、大块(>260)内存管理器,他们是独立管理的。


大块内存是从地址空间的高地址开始分配,中小块内存是从低地址开始分配的,大块和中小块分开处理可以减少内存碎片的产生。

(↑经测试,在FullDebugMode时都是从高地址开始分配)


中块内存管理器从操作系统以1.25M的大小获取内存块,这种内存块被叫做“中块池”,因为在应用程序申请内存时这种内存块会

再被细分为中块。没有使用的中块被串在双向链表里,一共有1024个这样的链表,而且由于中块的粒度是256byte,这就意味着

对每个申请的可能大小的内存块都有对应一个虚拟的容器。FastMM维护着为这些链表维护着一个两级的位图,所以要找到一个

合适大小且空闲的内存块并不需要挨个探查。当一个释放一个中块的时候,FastMM会检查和它相邻的块,如果相邻的块未使用,

FastMM就将它和刚刚释放的块合并,所以永远不可能有两个相邻的未用的块。

FastMM没有内存清理线程,要释放内存,必须手动调用FreeMem之类的函数。


在类似delphi这样的面向对象的语言,通常情况下内存的分配和释放都是小对象。在实测了大量delphi编写的程序后,平均下来,

超过99%的内存操作涉及的块都需要2k,因此针对这样的小块内存做优化很有必要。小块是从“小块池”分配的。小块池实际上就是

被分成很多等大小块的中块内存。

因此小块池只包含等大小的块,并且相邻的未用小块永远都不会合并,FastMM为每种大小的小块池维护一个双向链表,所以查找

指定大小的小块会非常迅速。


在内存中到处移动数据是典型的耗资源操作。因此,FastMM实现了一个非常只能的重分配算法,来尽量避免内存移动操作。

当需要扩大一块内存时,FastMM会将其扩大到以后可能会使用的大小,也就是会多扩展一些,以便下次扩展时不需要重新分配内存。

同样,当需要缩小一块内存时,除非FastMM明确地知道刚刚被裁减的内存不会再次被分配回去,否则这块内存不会被移除。


FastMM通过优化锁机制来进一步提升速度:小块,中块,大块内存是独立加锁的。调用GetMem时,如果最合适的块的类型被其他

线程锁住了的话,那么FastMM会向上尝试更大的块,这种设计大大减少了线程争夺资源的几率,提高了多线程应用程序的性能。
















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值