【发布时间】:2018-09-10 11:22:40
【问题描述】:
我有一个用于处理大型数据集的数据结构。它本质上充当磁盘数据的“视图”,根据请求从磁盘加载数据;它将尝试在内存中保留尽可能多的数据,以便在下次访问时不必从磁盘读取。当它检测到内存不足时,它会对引用计数为 0 的数据块进行“清理扫描”。它使用 _set_new_handler() 设置一个函数,当某些代码在某处尝试 malloc() 内存但可以不。这样,数据结构可以消耗尽可能多的内存,但在其他人需要一些内存时仍会“退避”。
现在我遇到了一些内存没有使用 malloc()(或 new())分配的问题。我第一次在调用 CreateDIBSection() 时开始看到它,我认为这是因为这个函数直接使用了 VirtualAlloc()。因此,当分配失败时,不会调用新的处理程序,而 VirtualAlloc 只会失败。 (我也有其他情况相同的情况,但我可以解决这些问题;所以 CreateDIBSection() 是我主要的问题“演示案例”;但使用该特定 API 解决问题并不能解决我的一般问题)
所以我的问题是 - VirtualAlloc() 是否有等效的 _set_new_handler() 或 VirtualAlloc() 失败时通知的另一种方式,以便我可以调用我的“清理内存”功能并再次尝试分配?或者,有没有办法拦截 VirtualAlloc() 调用,以便我可以检查每次分配的内存可用性,并在必要时进行清理?谢谢。
【问题讨论】:
-
CreateDIBSection不调用VirtualAlloc或在用户模式下分配任何内存。并且在VirtualAllocotNtAllocateVirtualMemory上不存在通知处理程序。只有你们自己设置了这个 api 的钩子 -
当你没有通过 hSection 时 CreateDIBSection 是如何分配内存的?还有其他低级内存分配方法吗?
-
他们从内核调用
NtAllocateVirtualMemory。您调用DeleteObject获取位图时,内存将是空闲的 -
这是 32 位应用程序吗?你怎么用完了虚拟内存来分配?而且我认为您还将页面锁定在 RAM 中?在虚拟内存操作系统(例如 Windows)上,“内存”是指分配了地址的东西,但可能在 RAM 或磁盘上,因此您似乎发明了一种复杂的方法来使您的应用程序在实现时中断绝对没有。
-
几乎所有此类行为的其他实例都依赖于在启动时分配的固定大小的缓冲区。请参阅 Java 的 -Xmx 标志。您可能想尝试使用 Large Address Aware 开关构建您的应用程序,以提供额外的 2GB VM 地址空间(假设至少是 64 位操作系统)。但是,使用 10yo 代码 - 谁能判断它是否真的会感知大地址......