♣贝斯特bst3322-www.bet3322.com-全球最奢华游戏平台

软件提交最近更新热门排行
您现在的位置:首页››软件教程››编程开发››Visual C++››c+开发工具

编程宝典 保持C/C++程序代码可伸缩性

2006-12-27 01:10作者:佚名来源:天极yesky浏览:1344 评论:0

  在今天,已有许多的32位应用程序感到,在32位平台上可用的虚拟内存受到了一定的限制,对程序开发者来说,即使是开始关注64位平台时,也不得不维护软件的32位版本,这就需要一种方法,以使代码的两个版本都保持相当的可伸缩性。

  目前的内存剖析工具能帮助确定,当程序达到峰值内存使用量时,都发生了什么,但是这些工具都过于关注已分配的内存块,而不是已提交的虚拟内存地址空间,而这两种衡量标准没有直接的相关性,如内存泄漏、内存碎片、内存块内的空间浪费、或过度延迟的内存单元重新分配这些因素,都会导致不必要的虚拟内存提交。运行时分析工具如IBM Rational Purify或Parasoft Inuse均可以提供内存泄漏及已用内存的描述,这些信息是非常有用的,但是,一个特殊的内存块也许可能、也许不可能影响到虚拟内存覆盖区,另外,甚至一个有碎片的内存堆中的一个小块,也能直接影响到虚拟内存覆盖区。从另一方面来说,在此范围内的任意内存块--甚至泄漏的块,对虚拟内存覆盖区来说,也不会与之有什么关系,除非每一个此范围内有用的内存块能重新分配到一个更紧凑的范围内,这就有点像Java或托管程序的垃圾回收机制,但对大多数C/C++本地应用程序来说,就绝对不可能了,因为在虚拟内存空间中,它们内存块的位置是不确定的。

  至于本地代码,不必要的虚拟内存使用,这个实际的问题,比未清理的内存块这个理论上的问题,更加有实质性。未清理的内存块可能导致虚拟内存的浪费,造成过多的系统开销,但或者不会;这完全依赖于堆管理器是否提交了更多的虚拟内存,以支撑这种浪费。某些很小的未使用的内存块,不会引起不必要的堆"扩展"。与其让你来猜哪一个或多少已浪费的内存块导致了堆扩展,倒不如学会怎样判定出有意义的浪费是什么。当堆中包含不再使用的内存块时,此时通过加入对未缩减堆的检查,就能确定出与你的程序虚拟内存要求有很大关系的、必须进行的内存块清理。

  为找出哪一个堆中的内存块需多留意,必须在程序中加入一些额外的代码,以跟踪内存堆范围及已分配的内存块。对额外的代码进行条件编译,生成一个特定的版本,也许是一个不错的办法。

  为达到此目的,需编写自定义的内存分配例程,并跟踪每一个内存块,另有一个自定义的释放例程,且跟踪虚拟内存中堆的位置,请参见例1与例2的伪代码算法。可能还需编写自定义的访问函数以标记出访问过的内存块,以便于在适当的时候释放虚拟内存,所有这些并不需要过多的内存开销。另一方面,如果你的程序以堆的形式使用了大量的内存,那么将会极大地降低性能,此处的方法也不是长久之计。

  例1:

/* 输入参数*/
ADDRESS triggerAddr
SIZE triggerSize
LIST a list of tracked heap ranges

IF (the virtual memory at triggerAddr is tracked on the list as part of a heap range)
DO
IF (triggerAddr + triggerSize >
(the tracked upper boundary of that heap range))
DO
/* 一个现有的堆范围被扩展 */

make system call(s) to determine the base and extent of the newly committed range that contains the addresses from triggerAddr to (triggerAddr + triggerSize)

update the size of the tracked heap range to indicate its new upper limit
END
END
ELSE DO
/* 在triggerAddr中有一个新的堆范围 */

make system call(s) to determine the base and extent of the newly committed range that contains the addresses from triggerAddr to (triggerAddr + triggerSize)

track the new committed range in the list of heap ranges
END

  例2:

/* 输入参数 */
ADDRESS triggerAddr
SIZE triggerSize
LIST a list of tracked heap ranges

/* 局部变量 */
ADDRESS origRangeBase
SIZE origRangeSize
BOOL bFoundChange

bFoundChange = FALSE

IF (the virtual memory at triggerAddr is not tracked on the heap range list as part of a heap range)
DO
/*似乎我们已经清楚此次释放了。*/
END
ELSE IF (an access exception occurs when memory at triggerAddr is read)
DO
bFoundChange = TRUE
END

IF (bFoundChange) DO
/*因为之前内存块占用的空间被释放了,所以堆占用的虚拟内存范围就改变了。*/

make system calls to determine the bases and extents of the tracked committed heap ranges in the immediate vicinity of the decommitted range that includes the addresses from triggerAddr to (triggerAddr + triggerSize)

/*更新堆范围跟踪,以反映剩余提交的范围 */

IF (any portion of the tracked heap range that contained the block at TriggerAddr is still committed)
DO
update the heap range list to track just the portion(s) of that range that remain committed
END
ELSE
DO
delete the list element that tracks the range
END
END

天极yesky

Tags:责任编辑:mynewasp
顶一下(56)
91.8%
    1. C语言编程C语言编程软件

      C语言编程软件专区提供了最好用最全面的C语言编程软件下载。

    1. Python开发工具Python开发工具

      新云软件园Python下载专区提供了Python核心编程和Python开发工具下载,另外还提供了python基础教程等诸多内容。

    1. Go语言Go语言

      新云软件园Go语言下载专区提供了最全面最好用的Go语言编程软件Golang和Go语言开发工具以及Go语言开发环境和Go语言开发工具安装包免费下载。

    文章评论 新云下载QQ群:① 7551827使用手机微信搜索 微信号:xinyunshouyou 关注我们 有更多惊喜!!

    请自觉遵守互联网相关政策法规,评论内容只代表网友观点,与本站立场无关!
      验证码:     登录   注册
    网友评论

    关注新云安卓游戏网