4

最近、プロジェクトでluaのメモリ使用量を追跡しようとしていますが、このタスクにlua_Allocカスタムアロケータを使用するというアイデアに出くわしました。まあ、アロケータコードは簡単に見えます、そしてそれはうまくいくようです。

しかしすぐに、この小さな関数は2つの課題に直面しました。1。
出力される結果は、collectgarbage('count')によって与えられる値とはかなり異なります。
2.現在のメモリ使用量がMバイトであると仮定し、いくつかのnil参照を入力してgcを呼び出すと、メモリ使用量はMバイトより大きくなります。例:A return、B return、C return、...、collectgarbage()

さて、luaを正しく使えば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に関する入力シーケンス:

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
4

1 に答える 1

6

Luaのドキュメントに記載されているように、キロバイトcollectgarbage('collect')単位の値が返されます。1KiB==1024バイト。したがって、19.4775390625KiBを使用していると言うと、それは19945バイトに変換されます。これは、アロケータが取得した多くの値の1つとまったく同じです。collectgarbage

あなたのメモリチェック機能は、Luaがちょうど一瞬で得たもの、つまり戻った瞬間にのみ一致しcollectgarbageます。その前または後に発生するLuaの割り当て/割り当て解除(print値を表示するための呼び出しに必要なものなど)は、カウントをオフにします。

要するに、そのような精度がまったく不可能な場合、バイト精度を期待しているのです。少なくとも、そこにあるコードではありません。

一般的に、あなたはそれについて心配するべきではありません。

于 2012-04-16T02:31:54.213 に答える