2012-04-15 16 views
2

我想最近在跟蹤我們的項目的LUA內存使用情況不同了,我整個使用lua_Alloc定製的靈光乍現這個任務的分配器。那麼,分配器代碼看起來很簡單,看起來工作正常。使用自定義的Lua分配器來算內存使用情況,但其結果是從collectgarbage(「計數」)

但是很快,這個小函數遇到了兩個挑戰:
1.它輸出的結果與collectgarbage('count')給出的值有很大的不同,
2.假設當前的內存使用量爲M字節,則我們輸入一些零引用並調用gc,內存使用量將會大於M字節。例如:A return,B return,C return,...,collectgarbage()

嗯,我聽說如果你正確使用lua,就不會有內存泄漏,所以我認爲我在做錯了什麼統計內存使用情況。請幫我弄明白。提前致謝。

該可編譯的代碼如下附:

extern "C" 
{ 
#include "lua.h" 
#include <lauxlib.h> 
#include <lualib.h> 
}; 

#include <cstdio> 
#include <string> 
#include <cstdlib> 

using namespace std; 

struct Tracker 
{ 
    size_t m_usage; 
}g_tracker; 

void* 
Allocator(void* ud, void* ptr, size_t osize, size_t nsize) 
{ 
    Tracker* pTracker = (Tracker*)ud; 
    void* pRet = NULL; 
    if(nsize == 0) 
    { 
     pTracker->m_usage -= osize; 
     //printf("Free %d bytes; ", osize); 
     free(ptr); 
    } 
    else 
    { 
     pTracker->m_usage -= osize; 
     //printf("first Free %d bytes; ", osize); 
     pTracker->m_usage += nsize; 
     //printf("then alloc %d bytes; ", nsize); 
     pRet = realloc(ptr, nsize); 
    } 

    //printf("current usage: %d bytes\n", pTracker->m_usage); 
    return pRet; 
} 

int main() 
{ 
    lua_State* L = lua_newstate(Allocator, &g_tracker); 
    luaL_openlibs(L); 

    char buf[4096]; 
    while(true) 
    { 
     fgets(buf, 4096, stdin);       

     if(strlen(buf) > 1 && 0 != luaL_dostring(L, buf)) 
     { 
      const char* errmsg = lua_tostring(L, -1); 
      printf("%s\n", errmsg); 
     } 

     printf("current usage: %d bytes \n", g_tracker.m_usage); 
    } 
} 

輸入序列約#2:

press enter 
current usage: 18867 bytes 
a=nil; b=nil; c=nil; 
current usage: 19311 bytes 
collectgarbage() 
current usage: 18900 bytes 
d=nil; e=nil; f=nil; 
current usage: 19345 bytes 
collectgarbage() 
current usage: 18900 bytes 
collectgarbage() 
current usage: 18900 bytes 
for a = 1, 1000, 1 do b = nil end; collectgarbage() 
current usage: 19206 bytes 
collectgarbage() 
current usage: 18900 bytes 
for i = 1, 1000, 1 do X = {}; for j = 1, 1000, 1 do X[j] = j end ; X = nil; collectgarbage() ; end 
current usage: 19391 bytes 
collectgarbage() 
current usage: 18900 bytes 
+1

「它輸出該結果是從由'collectgarbage(‘計數’)給出的值非常不同;'」如何「相當不同」是麼?始終更大,始終更小,等等?不要忘記:您獲得的價值是*千*字節 – 2012-04-15 16:40:20

+0

感謝您的回覆。具體而言,collectgarbage('count')總是返回小於分配者的數量。在這個小程序中,它會有數百個字節。 – zaexage 2012-04-16 02:06:48

+0

哦,我編輯了線程併發布了最小的完整代碼來重現這種情況 – zaexage 2012-04-16 02:09:15

回答

2

作爲Lua的文檔collectgarbage('collect')中所述返回千字節的值。 1KiB == 1024字節。因此,collectgarbage表示您使用的是19.4775390625KiB,即轉換爲19945字節。這與您的分配器獲得的許多值中的一個完全相同。

你的內存檢查功能將只匹配什麼的Lua得正好一個時刻:時刻,collectgarbage回報。在它之前或之後發生的任何Lua分配/釋放(例如爲了顯示值而調用print所需的分配/釋放)將會拋出您的計數。

總之,你期待字節精度當這樣的精度是不可能的。至少,不是你在那裏的代碼。

一般情況下,你不應該擔心。

+0

我認爲你是對的。 – zaexage 2012-04-16 05:11:15

+0

我在代碼中做了一些改動,並做了一些更多的測試,我認爲你的答案很好地解釋了#1;至於#2,(我已經發布了一組輸入序列),雖然初始值和中間值有一些區別,但我認爲這個分配器仍然可以作爲一種方法來檢查是否有泄漏。 – zaexage 2012-04-16 05:20:59