2012-04-15 3 views
2

최근 프로젝트에서 루아 메모리 사용량을 추적하려고하고 있는데 lua_Alloc 커스텀 할당 자. 음, 할당 자 코드가 쉽게 보이고, 잘 동작하는 것 같습니다.메모리 사용량을 계산하기 위해 커스텀 루아 할당자를 사용하지만 그 결과는 collectgarbage ('count')와 다릅니다

그러나이 작은 함수는 두 가지 문제가 발생했습니다.
1. 결과는 collectgarbage ('count')에서 제공 한 값과 상당히 다릅니다.
2. 현재 메모리 사용량을 알아내는 것은 M 바이트입니다. 그런 다음 몇 가지 nil 참조를 입력하고 gc를 호출하면 메모리 사용량이 M 바이트보다 커집니다. 예 : A return, B return, C return, ..., collectgarbage()

글쎄, 루아를 올바르게 사용하면 mem-leak가 발생하지 않는다고 들었습니다. 메모리 사용량을 계산합니다. 제발 이해해주세요. 미리 감사드립니다.

컴파일 가능한 코드가 아래에 부착되어

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 : 루아 문서 collectgarbage('collect')에 명시된 바와

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 ('count')에 의해 주어진 값과 상당히 다릅니다;" "상당히"다른 점은 무엇입니까? 꾸준히 크고 일관되게 작은 등? 그리고 당신이 얻는 가치는 * kilo * 바이트 인 것입니다. –

+0

답장을 보내 주셔서 감사합니다. 구체적으로, collectgarbage ('count')는 항상 할당 자보다 작은 수를 반환합니다. 이 작은 프로그램에서는 수백 바이트가됩니다. – zaexage

+0

오, 나는 상황을 재현하기 위해 스레드를 편집하고 가장 작은 전체 코드를 게시했습니다. – zaexage

답변

2

킬로바이트의 값을 반환한다. 1KiB == 1024 바이트. 따라서 collectgarbage에서 19.4775390625KiB를 사용 중이라고 말하면 19945 바이트로 변환됩니다. 할당 자에게있는 많은 값 중 하나와 정확히 같습니다.

메모리 검사 기능은 Lua가 정확히 한 순간에 얻는 것 : collectgarbage이 반환하는 순간에만 일치합니다. 값을 표시하기 위해 print에 대한 호출에 필요한 것과 같이 그 이전이나 이후에 발생하는 루아 할당/할당 해제는 카운트를 해제합니다.

간단히 말해서 정확도가 정확하지 않은 경우 바이트 정확도가 기대됩니다. 적어도, 당신이 가지고있는 코드는 아닙니다.

일반적으로 걱정할 필요가 없습니다.

+0

당신이 옳다고 생각합니다. – zaexage

+0

코드에서 몇 가지 변경을 수행하고 테스트를 더 수행했습니다. 귀하의 대답이 1 위를 잘 설명한다고 생각합니다. # 2에 관해서는 (초기 값과 중간 값 사이에 약간의 차이가 있음에도 불구하고 입력 시퀀스의 그룹을 게시했습니다.)이 할당자를 여전히 누수가 있는지 확인하는 방법으로 사용할 수 있다고 생각합니다. – zaexage