在Linux上的LuaJIT中,所有VM maaged ram必须低于2GB进程内存边界,因为内部指针总是32位。因此,我想自己管理更大的分配(使用FFI和malloc
等),例如适用于大纹理,音频,缓冲区等。
我现在想确保将这些内容映射到上面 2GB boudary,因为这样他们就不会占用任何VM可管理的内存。
有没有办法malloc
或mmap
(没有映射文件,或者可能在SHM中)分配特定于该地址之上的指针?甚至不必占用2gig,只需将指针映射到更高(=非32位)的地址
答案 0 :(得分:4)
分配2 GB块。如果它位于限制之下,则分配另一个2 GB(这个必须高于2 GB,因为只有一个块的大小可以低于2 GB)。
/* Allocates size bytes at an address higher than address */
void *HighMalloc(size_t size, void *address) {
size_t mysize = (size_t)address;
void *y, *x;
if (mysize < size) {
mysize = size;
}
y = x = malloc(mysize);
if (x < address) {
/* The memory starts at a low address.
* mysize is so big that another block this size cannot fit
* at a low address. So let's allocate another block and
* then free the block that is using low memory. */
x = malloc(mysize);
free(y);
}
return x;
}
注意:强>
如果size
小于address
,则第二个malloc的低地址可能有足够的空间。这就是我在这种情况下增加分配大小的原因。所以不要用它来分配小内存块。分配一大块然后手动将它分成小块。
答案 1 :(得分:3)
唯一认为我知道(也许这不是最好的选择)是使用mmap
用于Linux。在某些情况下,我必须分配与特定值对齐的大内存块,所以我使用它(因为在这里你可以指定内存块的地址和长度)但它需要实现一些内存管理器单元,因为现在你是将管理分配(和发布)。
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
在此查看详细信息:http://man7.org/linux/man-pages/man2/mmap.2.html
要使其未映射到仅将flags
设置为MAP_ANONYMOUS
的任何文件:
MAP_ANONYMOUS
任何文件都不支持映射;它的内容是 初始化为零。 fd和offset参数被忽略; 但是,有些实现要求fd为-1 MAP_ANONYMOUS(或MAP_ANON)已指定且可移植 应用程序应确保这一点使用MAP_ANONYMOUS 仅在Linux上支持与MAP_SHARED的结合 内核2.4。
如果addr
为NULL,那么系统将为您选择可用的地址,但由于您要将其分配到2G以上,您需要管理已分配页面的列表,以便知道上面使用了哪些地址2G。另请注意,如果您指定addr=X
,并且mmap
将无法使用此地址,则它将不会失败,它只会选择另一个可以在没有任何失败指示的情况下使用的地址(除了返回指针不等于addr
)的事实。但是,您可以使用MAP_FIXED
标记来强制执行您提供的地址,如果mmap
无法使用它,则会失败(返回MAP_FAILED
)。
MAP_FIXED
不要将addr解释为提示:将映射精确放置 那个地址。 addr必须是页面大小的倍数。如果 addr和len指定的内存区域重叠页面 任何现有的映射,然后是重叠的部分 现有的映射将被丢弃。如果指定的话 地址无法使用,mmap()将失败。因为需要一个 一个映射的固定地址不太便携,使用这个 不鼓励选择。
修改强>
请注意,建议不要使用MAP_FIXED
,因为描述说明
如果addr和len指定的内存区域与任何现有映射的页面重叠,则将丢弃现有映射的重叠部分。
你甚至都不知道。更安全地检查addr
是否等于mmap
地址返回的内容。