在Linux上malloc指定地址或页面(指定“最小偏移量”)
在Linux的LuaJIT中,所有VM管理的内存都必须低于2GB的进程内存边界,因为内部指针始终是32位的。因此,我希望自己管理更大的分配(使用FFI和malloc等),例如大纹理、音频、缓冲区等。
现在,我想确保这些被映射到以上2GB的界限,因为它们不会占用任何VM可管理的内存。
有没有办法malloc或者mmap(没有映射文件,或者在SHM中)分配一个指针到特定于该地址之上?甚至不需要占用2G,只需要将我的指针映射到一个更高(=非32位)的地址即可。
我所知道的唯一方法(可能不是最佳选择)是在Linux上使用mmap。在有些情况下,我需要分配大块内存并将其对齐到特定值,所以我使用了它(因为你可以指定内存块的地址和长度),但需要实现一些内存管理器单元,因为此时你将要管理分配(和释放)。
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参数;但是,一些实现要求如果指定了MAP_ANONYMOUS(或MAP_ANON),则fd必须为-1,并且可移植的应用程序应确保这一点。仅当内核为2.4以后的Linux支持在MAP_SHARED结合使用MAP_ANONYMOUS时才支持。
如果addr为空,则系统将为您选择可用地址,但由于您想在2G以上分配它,因此您需要管理已分配页面的列表,以了解哪些地址在2G以上使用。请注意,如果指定addr=X,并且mmap无法使用此地址,则不会失败,它只会选择另一个可以使用的地址,而不会有任何失败指示(除了返回的指针不等于addr)。但是,您可以使用MAP_FIXED标志强制执行您提供的地址,如果mmap无法使用它,则会失败(返回MAP_FAILED)。
MAP_FIXED
不要将
addr解释为提示:将映射放置在该地址上。addr必须是页面大小的倍数。如果由addr和len指定的内存区域与任何现有映射的页面重叠,则现有映射的重叠部分将被丢弃。如果无法使用指定的地址,则mmap()将失败。由于为映射指定固定地址的要求不太可移植,因此不建议使用此选项。
编辑
请注意,不建议使用MAP_FIXED,因为如描述中所述
如果由
addr和len指定的内存区域与任何现有映射的页面重叠,则现有映射的重叠部分将被丢弃。
而您将不会知道。最好检查addr是否等于mmap返回的地址。
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
/* 分配一个 2GB 的内存块。如果该块位于地址的下限之下,再分配另一个 2GB 的内存块(这个必须在 2GB 之上,因为只有一个这么大的块可以放在 2GB 以下。)*/ 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) { /* 内存开始于低地址。 * mysize 太大,另一个同样大的块不能放在低地址上。 * 因此,让我们再分配另一个块, * 然后释放正在使用低地址内存的块。*/ x = malloc(mysize); free(y); } return x; }注意:
如果
size小于address,第二次调用malloc时可能在低地址有足够的空间。这就是为什么在这些情况下我增加了分配的大小。因此,不要使用它来分配小内存块。分配一个大块,然后手动将其分成更小的块。