c – 堆碎片和Windows内存管理器

c – 堆碎片和Windows内存管理器,第1张

概述我在我的程序中遇到内存碎片的麻烦,一段时间后无法分配非常大的内存块.我在这个论坛上看过相关的帖子 – 主要是 this.我还有一些问题. 我一直在使用内存空间profiler来获取内存的图片.我写了一个1行程序,其中包含cin>> VAR;并拍摄了记忆: alt text http://img22.imageshack.us/img22/6808/memoryk.gif 顶部圆弧 – 绿色表示空白 我在我的程序中遇到内存碎片的麻烦,一段时间后无法分配非常大的内存块.我在这个论坛上看过相关的帖子 – 主要是 this.我还有一些问题.

我一直在使用内存空间profiler来获取内存的图片.我写了一个1行程序,其中包含cin>> VAR;并拍摄了记忆:

alt text http://img22.imageshack.us/img22/6808/memoryk.gif
顶部圆弧 – 绿色表示空白处,黄色分配,红色表示.我的问题是右边分配的内存是什么?是主线程的堆栈吗?这个内存不会被释放,它分割了我需要的连续内存.在这个简单的1线程序中,分割没有那么糟糕.我的实际程序有更多的东西分配在地址空间的中间,我不知道它在哪里.我还没有分配那个内存.

>我该如何解决这个问题?我正在考虑切换到像nedmalloc或dlmalloc这样的东西.然而,这只适用于我自己明确分配的对象,而图中所示的分割不会消失?还是有办法用另一个内存管理器来替换CRT分配?
>说到对象,有没有为nedmalloc包装c,所以我可以使用新的和删除来分配对象?

谢谢.

解决方法 首先,感谢您使用我的工具.我希望你发现它有用,并且可以自由地提交功能请求或贡献.

通常,地址空间中固定点处的薄片是由其首选地址加载的链接dll引起的.在地址空间中加载的数据往往是Microsoft *** 作系统dll.如果这些 *** 作系统都可以在其首选地址中加载,那么 *** 作系统的效率更高,因为dll的只读部分都可以在进程之间共享.

你可以看到的切片是没有什么可担心的,它几乎没有任何东西从您的地址空间中删除.正如你所注意到的,但是,有些DLL在地址空间的其他点加载. IIRC shlwAPI.dll是一个特别糟糕的例子,加载大约0x2000000(再次是IIRC),它经常将大部分可用的地址空间分成两个较小的块.这样做的问题是,一旦DLL被加载,你可以做任何事情来移动这个分配空间.

如果您链接到DLL(直接或通过另一个DLL),没有什么可以做的.如果您使用Loadlibrary,您可以在释放该保留的内存之前,先获取首选地址,并强制将其重新定位到地址空间更多的地方.这并不总是奏效.

在引擎盖下,地址空间监视器使用VirtualqueryEx来检查进程的地址空间,但是还有另一个调用来自psAPI库,其他工具使用(例如Process Explorer)可以显示哪些文件(包括DLL)映射到地址空间.

如您所见,在2GB用户地址空间中,可能会很容易耗尽空间.从根本上说,你最好防止内存碎片简单地不需要任何大的连续的内存块.虽然难以适应,但是设计您的应用程序可以使用“中等大小”的块通常使地址空间的使用更加有效.

类似地,您可以使用分页策略,可能使用内存映射文件或Address Windowing Extensions.

总结

以上是内存溢出为你收集整理的c – 堆碎片和Windows内存管理器全部内容,希望文章能够帮你解决c – 堆碎片和Windows内存管理器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1254377.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存