mirror of
https://gitee.com/openLuat/LuatOS
synced 2025-08-17 22:18:03 +08:00
add: 添加用于lua内存分析的profiler库
用于分析lua虚拟机的内存变化,逐一打印malloc/free/realloc行为,记录次数,前后状态
This commit is contained in:
parent
01dd49fbfa
commit
0c5e9f10e5
33
components/mempool/profiler/bind/luat_lib_profiler.c
Normal file
33
components/mempool/profiler/bind/luat_lib_profiler.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "luat_base.h"
|
||||
#include "luat_malloc.h"
|
||||
#include "luat_malloc.h"
|
||||
#include "luat_timer.h"
|
||||
|
||||
static int l_profiler_start(lua_State *L) {
|
||||
luat_profiler_start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_profiler_stop(lua_State *L) {
|
||||
luat_profiler_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_profiler_print(lua_State *L) {
|
||||
luat_profiler_print();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "rotable2.h"
|
||||
static const rotable_Reg_t reg_profiler[] =
|
||||
{
|
||||
{ "start" , ROREG_FUNC(l_profiler_start)},
|
||||
{ "stop" , ROREG_FUNC(l_profiler_stop)},
|
||||
{ "print", ROREG_FUNC(l_profiler_print)},
|
||||
{ NULL, ROREG_INT(0)}
|
||||
};
|
||||
|
||||
LUAMOD_API int luaopen_profiler( lua_State *L ) {
|
||||
luat_newlib2(L, reg_profiler);
|
||||
return 1;
|
||||
}
|
27
components/mempool/profiler/include/luat_profiler.h
Normal file
27
components/mempool/profiler/include/luat_profiler.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef LUAT_PROFILER_H
|
||||
#define LUAT_PROFILER_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef struct luat_profiler_ctx
|
||||
{
|
||||
int tag;
|
||||
int ticks_start;
|
||||
int ticks_stop;
|
||||
uint32_t counter_malloc;
|
||||
uint32_t counter_free;
|
||||
uint32_t counter_realloc;
|
||||
uint32_t lua_heap_begin_used;
|
||||
uint32_t lua_heap_end_used;
|
||||
uint32_t sys_heap_begin_used;
|
||||
uint32_t sys_heap_end_used;
|
||||
}luat_profiler_ctx_t;
|
||||
|
||||
void* luat_profiler_alloc(void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
|
||||
int luat_profiler_start(void);
|
||||
int luat_profiler_stop(void);
|
||||
|
||||
void luat_profiler_print(void);
|
||||
|
||||
#endif
|
79
components/mempool/profiler/src/luat_profiler.c
Normal file
79
components/mempool/profiler/src/luat_profiler.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include "luat_base.h"
|
||||
#include "luat_malloc.h"
|
||||
#include "luat_profiler.h"
|
||||
|
||||
#define LUAT_LOG_TAG "profiler"
|
||||
#include "luat_log.h"
|
||||
|
||||
static luat_profiler_ctx_t ctx;
|
||||
|
||||
void* luat_profiler_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
|
||||
// TODO 加调试信息的head, 这样才能记录实际malloc和realloc的大小
|
||||
void* dst = NULL;
|
||||
if (ctx.tag == 0) { // 停用状态, 原样返回
|
||||
return luat_heap_alloc(ud, ptr, osize, nsize);
|
||||
}
|
||||
LLOGD("ud %p ptr %p oszie %08X nsize %08X", ud, ptr, osize, nsize);
|
||||
if (ptr == NULL && nsize == 0) {
|
||||
LLOGD("free NULL");
|
||||
return NULL;
|
||||
}
|
||||
// 如果指针不为NULL, 目标大小为0, 那就是free
|
||||
else if (ptr != NULL && nsize == 0) {
|
||||
LLOGD("call free %p", ptr);
|
||||
ctx.counter_free ++;
|
||||
dst = luat_heap_alloc(ud, ptr, osize, nsize);
|
||||
LLOGD("done free %p", ptr);
|
||||
return dst;
|
||||
}
|
||||
// 如果指针为NULL, 目标大小不为0, 那就是malloc
|
||||
else if (ptr == NULL && nsize > 0) {
|
||||
ctx.counter_malloc ++;
|
||||
LLOGD("call malloc %08X type %08X", nsize, osize);
|
||||
dst = luat_heap_alloc(ud, ptr, osize, nsize);
|
||||
LLOGD("call malloc %08X type %08X %p", nsize, osize, dst);
|
||||
return dst;
|
||||
}
|
||||
// 最后剩下realloc
|
||||
else {
|
||||
ctx.counter_realloc ++;
|
||||
LLOGD("call realloc %08X osize %08X", nsize, osize);
|
||||
dst = luat_heap_alloc(ud, ptr, osize, nsize);
|
||||
LLOGD("call realloc %08X osize %08X %p", nsize, osize, dst);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
int luat_profiler_start(void) {
|
||||
size_t total; size_t used; size_t max_used;
|
||||
LLOGD("start profiler");
|
||||
memset(&ctx, 0, sizeof(luat_profiler_ctx_t));
|
||||
ctx.tag = 1;
|
||||
luat_meminfo_luavm(&total, &ctx.lua_heap_begin_used, &max_used);
|
||||
LLOGD("%s luavm %ld %ld %ld", "profiler start", total, ctx.lua_heap_begin_used, max_used);
|
||||
luat_meminfo_sys(&total, &ctx.sys_heap_begin_used, &max_used);
|
||||
LLOGD("%s sys %ld %ld %ld", "profiler start", total, ctx.sys_heap_begin_used, max_used);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int luat_profiler_stop(void) {
|
||||
size_t total; size_t used; size_t max_used;
|
||||
LLOGD("stop profiler");
|
||||
ctx.tag = 0;
|
||||
luat_meminfo_luavm(&total, &ctx.lua_heap_end_used, &max_used);
|
||||
LLOGD("%s luavm %ld %ld %ld", "profiler stop", total, ctx.lua_heap_end_used, max_used);
|
||||
luat_meminfo_sys(&total, &ctx.sys_heap_end_used, &max_used);
|
||||
LLOGD("%s sys %ld %ld %ld", "profiler stop", total, ctx.sys_heap_end_used, max_used);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void luat_profiler_print(void) {
|
||||
size_t total; size_t used; size_t max_used;
|
||||
LLOGD("============================================");
|
||||
// 输出调用次数
|
||||
LLOGD("counter malloc %08X free %08X realloc %08X", ctx.counter_malloc, ctx.counter_free, ctx.counter_realloc);
|
||||
// 输出前后内存大小
|
||||
LLOGD("heap used at start: lua %08X sys %08X", ctx.lua_heap_begin_used, ctx.sys_heap_begin_used);
|
||||
LLOGD("heap used at stop : lua %08X sys %08X", ctx.lua_heap_end_used, ctx.sys_heap_end_used);
|
||||
LLOGD("============================================");
|
||||
}
|
29
demo/profiler/main.lua
Normal file
29
demo/profiler/main.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
-- LuaTools需要PROJECT和VERSION这两个信息
|
||||
PROJECT = "memtest"
|
||||
VERSION = "1.0.0"
|
||||
|
||||
--[[
|
||||
lua内存分析库, 未完成
|
||||
]]
|
||||
|
||||
-- sys库是标配
|
||||
_G.sys = require("sys")
|
||||
|
||||
sys.taskInit(function()
|
||||
sys.wait(1000)
|
||||
collectgarbage()
|
||||
collectgarbage()
|
||||
sys.wait(1000)
|
||||
profiler.start()
|
||||
while 1 do
|
||||
log.info("sys", rtos.meminfo("sys"))
|
||||
log.info("lua", rtos.meminfo("lua"))
|
||||
sys.wait(3000)
|
||||
end
|
||||
end)
|
||||
|
||||
-- 用户代码已结束---------------------------------------------
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后后面不要加任何语句!!!!!
|
|
@ -141,5 +141,6 @@ LUAMOD_API int luaopen_ftp( lua_State *L );
|
|||
LUAMOD_API int luaopen_hmeta( lua_State *L );
|
||||
LUAMOD_API int luaopen_sms( lua_State *L );
|
||||
LUAMOD_API int luaopen_errdump( lua_State *L );
|
||||
LUAMOD_API int luaopen_profiler( lua_State *L );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#include "luat_errdump.h"
|
||||
#endif
|
||||
|
||||
#ifdef LUAT_USE_PROFILER
|
||||
#include "luat_profiler.h"
|
||||
#endif
|
||||
|
||||
static int report (lua_State *L, int status);
|
||||
|
||||
lua_State *L;
|
||||
|
@ -137,7 +141,11 @@ int luat_main_call(void) {
|
|||
// 4. init Lua State
|
||||
int status = 0;
|
||||
int result = 0;
|
||||
#ifdef LUAT_USE_PROFILER
|
||||
L = lua_newstate(luat_profiler_alloc, NULL);
|
||||
#else
|
||||
L = lua_newstate(luat_heap_alloc, NULL);
|
||||
#endif
|
||||
if (L == NULL) {
|
||||
l_message("lua", "cannot create state: not enough memory\n");
|
||||
goto _exit;
|
||||
|
|
Loading…
Reference in New Issue
Block a user