代码之家  ›  专栏  ›  技术社区  ›  Raymond

如何在100MB的边界上分配内存?[副本]

  •  0
  • Raymond  · 技术社区  · 2 年前

    我需要分配具有大对齐(也可能在兆字节范围内)的大内存区域(兆字节)。VirtualAlloc函数家族似乎没有提供这样做的选项。

    为了实现这一点,我在Linux上所做的是对一个更大的区域进行mmap,这个区域足够大,可以保证其中包含一个具有所需对齐的足够大的区域,然后对大区域的开始和结束处不需要的区域进行munmap。

    举个例子,假设我需要4兆字节,在1兆字节的边界上对齐(即,在最低20位中具有零的区域的开始)。我会压缩5兆字节。假设我得到区域0x44ff000-0x49ff000。在该区域中包含区域0x4500000-0x4900000,该区域在1兆字节的边界上对齐。然后我将munmap 0x44ff000-0x4500000和0x4900000-0x49ff000。

    我可以在Win32上做类似的操作吗?如果我将VirtualProtect与PAGE_NOACCESS一起使用,内存会被释放吗?有更好的解决方案吗?

    0 回复  |  直到 14 年前
        1
  •  8
  •   Raymond Chen    14 年前

    是的,你可以使用同样的技术。 VirtualAlloc 大范围作为 MEM_RESERVE 。找到适当对齐的子范围并调用 VirtualAlloc 第二次在子范围内 MEM_COMMIT .

        2
  •  1
  •   Jan RingoÅ¡    2 年前

    从Windows 10版本1803(RS4,内部版本17134)和Server 2019开始,您可以使用 VirtualAlloc2 然后通过 MEM_ADDRESS_REQUIREMENTS 具有所需的对齐设置。

    例子:

    MEM_ADDRESS_REQUIREMENTS requirement;
    requirement.LowestStartingAddress = NULL;
    requirement.HighestEndingAddress = NULL;
    requirement.Alignment = 1024 * 1024 * 1024; // align to 1GB boundary
    
    MEM_EXTENDED_PARAMETER extended;
    extended.Type = MemExtendedParameterAddressRequirements;
    extended.Pointer = &requirement;
    
    VirtualAlloc2 (NULL, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE, &extended, 1);
    
        3
  •  0
  •   Necrolis    14 年前

    看看的来源 _aligned_malloc 在windows/MSVC crt中,使用相同的方法来对齐虚拟内存非常简单,我甚至可以说,只需更换其内部 malloc 呼叫(同样适用 _aligned_free ),这只允许使用 仅有一个的 系统调用。

    然而,为什么你需要如此大规模的对齐?您是否试图滥用地址位模式来获取快速内存块?