2013-06-19 31 views
3

我有以下qsort示例來嘗試luajit中的回調。但是它有一個內存泄漏(執行時爲luajit: not enough memory),這對我來說並不明顯。luajit qsort回調示例內存泄漏

有人可以給我一些關於如何創建一個適當的回調示例的提示嗎?

local ffi = require("ffi") 

-- =============================================================================== 

ffi.cdef[[ 
    void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)); 
]] 


function compare(a, b) 
    return a[0] - b[0] 
end 

-- =============================================================================== 

-- Explicitly convert to a callback via cast 
local callback = ffi.cast("int (*)(const char *, const char *)", compare) 

local data  = "efghabcd" 
local size  = 8 
local loopSize = 1000 * 1000 * 100. 

local bytes = ffi.new("char[15]") 

-- =============================================================================== 

for i=1,loopSize do 
    ffi.copy(bytes, data, size) 
    ffi.C.qsort(bytes, size, 1, callback) 
end 

平臺:OSX 10.8 luajit:2.0.1

+0

更新的描述更加具體,並固定在代碼中的錯誤的變量名稱。 – camillobruni

+0

你可以通過在循環中放置一個'collectgarbage()'調用來解決它 – finnw

+1

爲其他人添加信息 - Mike只是修復了這個問題 - http://www.freelists.org/post/luajit/Beginners-FFI-callback-內存泄漏,2 – malkia

回答

1

這個問題似乎是LUA不會繼續執行嚴格的循環內進行完全的垃圾收集循環的機會。正如評論所暗示的,你可以通過在循環中自己調用collectgarbage()來解決這個問題。

請注意,在每次迭代中調用collectgarbage()都會影響您正在進行的任何操作的時間。爲了儘量減少這種情況,您應該設定一個閾值來限制collectgarbage()如何被通常稱爲:

local memthreshold = 2^20/1024 
local start = os.clock() 
for i = 1, loopSize do 
    ffi.copy(bytes, data, size) 
    ffi.C.qsort(bytes, size, 1, callback) 
    if collectgarbage'count' > memthreshold then 
     collectgarbage() 
    end 
end 
local elapse = os.clock() - start 
print("elapsed:", elapse..'s') 
+0

在這種情況下,使用'collectgarbage()'解決症狀。如上面評論所述,這是一個錯誤。 – camillobruni

+1

@ dh82它看起來像最新的LuaJIT-2.0.2下載仍然存在這個錯誤。我只是用mingw構建它並重新測試你的示例腳本。它仍然沒有足夠的內存錯誤。 – greatwolf

+1

@greatwolf正確,LuaJIT-2.0.2於2013-06-03發佈,並且該錯誤在2013年6月20日(17天后)修復,它出現在郵件列表中。所以,如果你遇到這個問題,只需從git HEAD編譯,這是Mike Pall推薦的,如果可以的話,順便說一句。看起來在他的工作流程中,即使它們未被髮布,git頭總是包含具有最新修復的穩定版本。 – Aktau