Bud*_*ric 9 c++ windows memory-management
我的程序中存在内存碎片问题,一段时间后无法分配非常大的内存块.我已经阅读了这个论坛上的相关帖子 - 主要是这个.我还有一些问题.
我一直在使用内存空间分析器来获取内存的图片.我写了一个包含cin >> var的1行程序; 并拍下了记忆的照片:
alt text http://img22.imageshack.us/img22/6808/memoryk.gif 顶部弧线的位置 - 绿色表示空白,黄色分配,红色提交.我的问题是右侧分配的内存是什么?它是主线程的堆栈吗?这个内存不会被释放,它会分裂我需要的连续内存.在这个简单的1行程序中,拆分并不是那么糟糕.我的实际程序在地址空间的中间分配了更多的东西,我不知道它来自哪里.我还没分配那个记忆.
我该如何解决这个问题?我想改用像nedmalloc或dlmalloc这样的东西.但是,这只适用于我自己明确分配的对象,而图片中显示的分割不会消失?或者有没有办法用另一个内存管理器替换CRT分配?
说到对象,是否有适用于c ++的nedmalloc包装器,所以我可以使用new和delete来分配对象?
谢谢.
CB *_*ley 12
首先,感谢您使用我的工具.我希望您觉得它很有用,并随时提交功能请求或贡献.
通常,地址空间中固定点处的薄片是由链接的dll加载到其首选地址引起的.在地址空间中加载高的那些往往是Microsoft操作系统dll.如果操作系统可以全部加载到它们的首选地址,那么它对于操作系统来说效率更高,因为这些dll的只读部分都可以在进程之间共享.
您可以看到的切片无需担心,它几乎不会削减您的地址空间.正如您所指出的那样,有些dll会加载到地址空间的其他位置.IIRC shlwapi.dll是一个特别糟糕的例子,加载大约0x2000000(再次是IIRC),它经常将大部分可用地址空间分成两个较小的部分.这个问题是,一旦加载了DLL,你就无法移动这个分配空间.
如果你链接DLL(直接或通过另一个DLL),你无能为力.如果您使用,LoadLibrary您可以偷偷摸摸并保留其首选地址,强制将其重新定位 - 通常在地址空间中更好的地方 - 然后释放该保留的内存.但这并不总是有效.
在引擎盖下,地址空间监视器用于VirtualQueryEx检查进程的地址空间,但还有来自psapi库的另一个调用,其他工具使用它(例如Process Explorer),它可以显示哪些文件(包括DLL)映射到哪个部分地址空间.
正如您所发现的那样,在2GB用户地址空间中耗尽空间可能非常容易.从根本上说,你最好的防御内存碎片只是不需要任何大的连续内存块.尽管难以改装,但设计应用程序以使用"中型"块通常可以大大提高地址空间的使用效率.
类似地,您可以使用分页策略,可能使用内存映射文件或Address Windowing Extensions.