memory - 使用自定义 Lua 分配器计算内存使用情况,但其结果与 collectgarbage ('count' 不同)

标签 memory garbage-collection lua allocator

我最近正在尝试跟踪我们项目中的 lua 内存使用情况,我遇到了使用 lua_Alloc 自定义分配器来完成此任务的想法。好吧,分配器代码看起来很简单,而且工作正常。

但很快,这个小功能就遇到了两个挑战:
1.它输出的结果与collectgarbage('count')给出的值有很大的不同;
2.假设当前的内存使用量为M字节,那么我们输入一些nil引用并调用gc,内存使用量会大于M字节。例如:A 返回、B 返回、C 返回、...、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

最佳答案

如 Lua 文档 collectgarbage('collect') 中所述以千字节为单位返回一个值。 1KiB == 1024 字节。因此,当 collectgarbage说您使用的是 19.4775390625KiB,即转换为 19945 个字节。这恰好等于您的分配器获得的许多值之一。

你的内存检查函数只会匹配 Lua 在某一时刻得到的:collectgarbage 的那一刻。返回。在它之前或之后发生的任何 Lua 分配/解除分配(例如调用 print 以显示值所必需的那些)都会使您的计数中断。

简而言之,当这种准确性不可能时,您期望字节准确性。至少,不是你在那里的代码。

一般来说,您不必担心。

关于memory - 使用自定义 Lua 分配器计算内存使用情况,但其结果与 collectgarbage ('count' 不同),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10161699/

相关文章:

java - 操纵内存占用

python - ctypes内存管理: how and when free the allocated resources?

php - 在脚本启动时最小化 PHP 内存使用

java - fragment 销毁后的 fragment 对象; GC什么时候收集它们?

android - 我怎样才能强制Android垃圾收集旧的套接字信息?

Lua 浮点运算

cocoa - NSMutableArray initWithContentsOfFile 内存泄漏

macos - 为什么 Swift 不自动处理循环引用(强引用循环)

lua - 如何读取文本文件并将数据存储在数组中

lua - 替代 Lua 中的模数