gpt4 book ai didi

windows - 强制 Windows 在某些地方加载 DLL,以使内存碎片最少

转载 作者:可可西里 更新时间:2023-11-01 12:47:30 25 4
gpt4 key购买 nike

我的应用程序需要大量内存和大数据结构才能执行其工作。应用程序通常需要超过 1 GB 的内存,在某些情况下,我的客户确实需要使用 64 位版本的应用程序,因为他们有几 GB 的内存。

在过去,我可以很容易地向用户解释,如果内存达到 1.6 到 1.7 GB 的内存使用量,那就是“内存不足”或非常接近“内存不足”的情况,他们需要减少他们的内存或移动到 64 位版本。

去年我注意到应用程序通常只使用了大约 1 GB 就已经耗尽内存。经过一些调查,这个问题的原因似乎是内存碎片。我使用 VMMAP(一种 SysInternals 实用程序)查看我的应用程序的内存使用情况,并看到如下内容: Address Space Fragmentation

橙色区域是我的应用程序分配的内存。紫色区域是可执行代码。

正如您在图像的下半部分看到的那样,紫色区域(即 DLL)被加载到许多不同的地址,导致我的内存碎片化。如果我的客户没有大量数据,这并不是真正的问题,但如果我的客户的数据集占用超过 1 GB,并且应用程序的一部分需要大块内存(例如 50 MB),它可能会导致内存分配失败,从而导致我的应用程序崩溃。

我的大部分数据结构都是基于 STL 的,通常不需要大块的连续内存,但在某些情况下(例如非常大的字符串),确实需要有一个连续的内存块。不幸的是,并不总是可以更改代码以使其不需要这样一个连续的内存块。

问题是:

  • 如何在不对客户计算机上的所有 DLL 显式使用 REBASE 或不显式加载所有 DLL 的情况下影响 DLL 在内存中的加载位置。
  • 有没有办法在您自己的应用程序 list 文件中指定 DLL 的加载地址?
  • 或者有没有办法告诉 Windows(通过 list 文件?)不要分散 DLL(我认为这种分散称为 ASLR)。

当然,最好的解决方案是我可以从我的应用程序的 list 文件中进行影响的解决方案,因为我依赖于 Windows 对 DLL 的自动/动态加载。

我的应用程序是一个混合模式(托管+非托管)应用程序,尽管应用程序的主要部分是非托管的。

有什么建议吗?

最佳答案

首先,您的虚拟地址空间碎片不一定会导致内存不足的情况。如果您的应用程序必须分配适当大小的连续 内存块,就会出现这种情况。否则碎片的影响应该很小。

您说您的大部分数据都是“基于 STL 的”,但是如果例如您分配了一个巨大的 std::vector,您将需要一个连续的内存块。

据我所知,无法在加载时指定 DLL 的首选映射地址。所以只有两个选择: rebase (rebase)(DLL 文件),或者自己实现 DLL 加载(当然这不是微不足道的)。

通常您不需要对标准 Windows API DLL 进行 rebase ,它们会非常紧密地加载到您的地址空间中。碎片可能来自某些第 3 方 DLL(例如 Windows 钩子(Hook)、防病毒注入(inject)等)

关于windows - 强制 Windows 在某些地方加载 DLL,以使内存碎片最少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8170502/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com