为什么LuaJIT的内存在64位平台上限制为1-2 GB?

时间:2016-02-02 13:57:52

标签: lua luajit

在64位平台上,LuaJIT只允许最多1-2GB的数据(不包括用malloc分配的对象)。这种限制来自哪里,为什么这比32位平台还要少?

2 个答案:

答案 0 :(得分:12)

LuaJIT旨在使用32位指针。在MAP_32BIT平台上,限制来自使用mmapMAP_32BIT标记。

  

MAP_32BIT(自Linux 2.4.20,2.6起):

     

将映射放入进程地址空间的前2 GB。对于64位程序,仅在x86-64上支持此标志。添加它是为了允许在前2GB内存中的某个位置分配线程堆栈,以便提高某些早期64位处理器的上下文切换性能。

基本上使用此标志限制为前31位,而不是名称所暗示的前32位。查看here,了解Linux内核中使用malloc的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状态内的对象,可以通过使用x86来克服,x64将在较低的32位地址空间之外进行分配。此外,可以在32位模式下使用{{1}} {{1}}版本,并可以访问完整的4GB。

查看这些链接以获取更多信息:

答案 1 :(得分:0)

由于最近patch luajit的2GB内存限制可以解决。

要进行测试,请克隆this repo并使用定义的msvcbuild.bat gc64 符号进行构建:

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)

我使用以下代码测试内存分配:

not enough memory

在我的计算机上TypeVar错误发生之前分配了48GB。

enter image description here