相当于 VirtualAlloc() 的_set_new_handler?

Equivalent of _set_new_handler for VirtualAlloc()?

本文关键字:set new handler VirtualAlloc 相当于      更新时间:2023-10-16

我有一个用于处理大型数据集的数据结构。它本质上充当磁盘上数据的"视图",根据请求从磁盘加载数据;它将尝试在内存中保留尽可能多的数据,以便在下次访问时不必从磁盘读取。当它检测到内存不足时,它会对引用计数为 0 的数据块进行"清理扫描"。它使用 _set_new_handler(( 来设置一个函数,当某些代码在某处尝试 malloc(( 内存但不能时调用此清理。这样,数据结构可以消耗尽可能多的内存,但当其他人需要一些内存时,它仍然会"退缩"。

现在我遇到了一些内存没有使用 malloc(((或 new(((分配的问题。我第一次在调用 CreateDIBSection(( 时开始看到它,我认为这是因为这个函数直接使用 VirtualAlloc((。因此,当分配失败时,不会调用新的处理程序,并且 VirtualAlloc 会失败。(我也有其他情况相同的情况,但我可以解决;所以CreateDIBSection((是我的主要"演示案例";但是使用该特定API解决不会解决我的一般问题(

所以我的问题是 - VirtualAlloc(( 是否有等效的 _set_new_handler((,或者另一种方式可以在 VirtualAlloc(( 失败时收到通知,以便我可以调用我的"清理内存"功能并再次尝试分配?或者,有没有办法拦截 VirtualAlloc(( 调用,以便我可以检查每个分配的内存可用性,并在必要时进行清理?谢谢。

">

内存"不应被视为基于现代虚拟内存的操作系统上的RAM - 它只是一个保留地址范围,可能由页面文件或其他一些映射文件视图支持。内存由操作系统根据需要分页进出 RAM,但实际上应将其视为磁盘而不是 RAM 分配。

在尝试构建用户模式内存"缓存"时,必须注意确保考虑到这一点,因为幼稚的尝试将导致净性能损失,因为实际上不会在 RAM 中缓存任何额外的内容,并且将有不必要的额外页面文件分配给页面输入和输出。

考虑到这一点,我可以建议:

  • 使用MapViewOfFile(和相关API(创建文件"视图"。这为操作系统提供了最佳提示,即您正在查看的文件根据需要直接从其自己的字节分页到 RAM 中,并确保您不会浪费地将字节从源文件复制到页面文件中。

  • 如果无法重新生成为 64 位应用,请使用应用上的/LARGE_ADDRESS_AWARE 链接器开关获取额外的 2GB 潜在 VM 分配。

  • 确定分配的一些可配置限制:有关其他应用程序如何处理此问题的示例,请参阅 Java 运行时 -Xmx 标志。

  • 还可以使用地址窗口化扩展插件来管理对来自 32 位应用的"大型"分配的访问。

  • 或者考虑使用 64 位
  • 合作伙伴应用加载文件,然后使用共享文件节来管理 64 位应用所做的分配的共享窗口。

实际上,我认为使用文件映射来创建文件的视图(或多个视图(将最容易实现并提供合理的性能(如果不是最佳性能(-即使视图未在32位进程中映射,这并不意味着64位底层操作系统不能或不会将这些字节保留在其文件IO缓存中的RAM中。