在64位平台上,LuaJIT仅允许最多1-2GB的数据(不包括分配的对象malloc).这种限制来自何处,为什么这比32位平台还要少?
Ada*_*dam 11
LuaJIT旨在使用32位指针.在x64平台上,限制来自使用mmap和MAP_32BIT标志.
MAP_32BIT(自Linux 2.4.20,2.6):
将映射放入进程地址空间的前2 GB.对于64位程序,仅在x86-64上支持此标志.添加它是为了允许在前2GB内存中的某处分配线程堆栈,以便改善某些早期64位处理器的上下文切换性能.
基本上使用此标志限制为前31位,而不是名称建议的前32位.看看这里有一个很好的概述MAP_32BITLinux内核中使用的1GB限制.
即使你的内容超过1GB,LuaJIT作者也解释了为什么这对性能有害:
- 完整的GC比分配本身多花费50%的时间.
- 如果GC已启用,则会使分配时间加倍.
- 为了模拟真实的应用程序,对象之间的链接在第三次运行中随机化.这使GC时间加倍!
这只是1GB!现在想象一下使用8GB - 一个完整的GC循环会让CPU忙碌24秒!好的,所以正常模式是使用增量GC.但这只意味着开销高出约30%,它在分配之间混合,每次都会驱逐CPU缓存.基本上你的应用程序将由GC开销占主导地位,你会开始怀疑为什么它很慢....
tl;博士版:不要在家里试试.GC需要重写(推迟到LuaJIT 2.1).
总而言之,1GB限制是Linux内核和LuaJIT垃圾收集器的限制.这仅适用于LuaJIT状态内的对象,可以通过使用来解决malloc,它将在较低的32位地址空间之外进行分配.此外,它可以在32位模式下使用x86构建,x64并可以访问完整的4GB.
查看这些链接以获取更多信息:
由于最近的补丁luajit 2GB 内存限制可以解决。
要进行测试,请克隆此 repo并使用LUAJIT_ENABLE_GC64定义的符号构建:
msvcbuild.bat gc64
Run Code Online (Sandbox Code Playgroud)
或XCFLAGS+= -DLUAJIT_ENABLE_GC64在Makefile
我使用此代码来测试内存分配:
local ffi = require("ffi")
local CHUNK_SIZE = 1 * 1024 * 1024 * 1024
local fraction_of_gb = CHUNK_SIZE / (1024*1024*1024)
local allocations = {}
for index=1, 64 do
local huge_memory_chunk = ffi.new("char[?]", CHUNK_SIZE)
table.insert(allocations, huge_memory_chunk)
print( string.format("allocated %q GB", index*fraction_of_gb) )
local pause = io.read(1)
end
print("Test complete")
local pause = io.read(1)
Run Code Online (Sandbox Code Playgroud)
not enough memory在我的机器上出现错误之前分配了 48GB 。
| 归档时间: |
|
| 查看次数: |
4944 次 |
| 最近记录: |