lua内存泄露检测原理

[Lua]Lua内存泄露检测原理 lua内存泄露 首先第一点,lua中的内存泄露和我们所说的c/c++中的内存泄露本质上是不一样的。 lua中有垃圾回收机制(GC),所以理论上是不会有内存泄露的。当它进行GC的时候,会从根部开始扫描所有的对象,如果某个地方对这个对象还有引用,就不会把这个对象内存collect,这个对象就没有被GC。所以lua中的内存泄露是指那些:已经没有被使用了,但外部依然还有引用存在的对象。 --函数 阅读详情


上次写了一个lua内存泄露检测的脚本,现在将它的实现原理拿出来和大家分享一下,希望能有所帮助。

lua内存泄露:

        首先第一点,lua中的内存泄露和我们所说的c/c++中的内存泄露本质上是不一样的。

        lua中有垃圾回收机制(GC),所以理论上是不会有内存泄露的。当它进行GC的时候,会从根部开始扫描所有的对象,如果某个地方对这个对象还有引用,就不会把这个对象内存collect,这个对象就没有被GC。

        所以lua中的内存泄露是指那些:已经没有被使用了,但外部依然还有引用存在的对象。

举个例子:函数中应该被申明为local的对象忘记加local

local function test()
    testTable = {} --这个testTabel会被存放在全局表_G中,GC时由于此对象还有引用存在,所以这里总是会有一个table泄露。
    local mt = {} --mt加了local修饰,函数调用完后,引用也不复存在了,GC时会被回收。
    setmetatable(testTable, mt)
end


 

检测原理:

        lua中支持垃圾回收机制的对象有五种:string,table,function,full userdata,thread。而他们的引用直接或间接的保存到:lua_state对象,_G全局表,Registry注册表,global_state->mt中。

        在脚本中:
                           运行的lua脚本本身就是lua_state。
                           _G就是_G全局表。
                           Registry表可以用debug.getregistry获取。
                           global_mt可以用debug.getmetatable获取。
 

        所以我们就可以在脚本层次实现内存泄露的检测模块。

        在搜索时需要注意的几点:
        1、table 额外搜索metatable,若metatable中的__mode取值为”k"、"v"或者”kv"需特殊处理(补充中有说明)
        2. function 额外搜索 enviroment,也是一个table。额外搜索upvalues,这个可以是任何类型。
        3. 由于userdata在script层次不能被修改,所以搜搜他的metatable吧
        4. thread对象就是coroutine对象,在script中一般都不会创建多个coroutine,所以在脚本中没搜索它。若是需求的话,获取到它的线程函数,然后再按照第2步操作就可以了。
 
搜索流程图(_G表):
 
 
在检测泄露之前,先搜索一下所有的对象,保存好起始的内存状态,在程序执行之后执行几次GC操作,然后再进行一次搜索,对比两次的结果,多出来的那些就有可能是内存泄露了。
 
补充:

lua中有一种叫weak表的东东,它的metatable中的__mode被设置为“k","v"或者”kv",表示保存在它中的键或值或键值都是一种弱引用状态。
若一个对象的所有引用都是弱引用了,那么这个对象也会被GC回收掉,所以对应的weak表中此对象的入口就没有了。

所以我们可以用另外一种实现:就是把用户自己创建的资源对象统统都丢到weak表中,运行完程序后强制GC,然后去查看weak表,若表中还保存着那个对象,就意味着这个对象还有外部引用(相对弱引用我们就叫它为强引用吧),资源没有被GC掉,所以我们可以说这个对象很有可能是内存泄露了。


lua中检测内存泄露 阅读详情

相关推荐

eBPF与BCC实战:零开销实时追踪C/C++内存泄露

内存管理是C/C++开发的核心基础,内存泄露则是其中最常见且棘手的顽疾之一。其原理在于程序动态分配的内存未能正确释放,导致系统可用内存被持续蚕食,最终引发性能下降甚至崩溃。传统工具如Valgrind虽能检测,但巨大的性能开销使其难以应用于生产环境。eBPF技术通过在内核安全沙盒中运行验证过的程序,以近乎零损耗的方式动态追踪系统事件,实现了高性能的实时观测。基于eBPF的BCC工具箱提供了memleak等利器,能够挂钩malloc、free等内存操作,精准统计未释放的分配及其调用栈。这项技术的核心价值在于,它

dezhen7015的博客 364

Lua的内存泄露问题

Lua内存泄漏 定义:已经没有使用的,但外部依然有引用的对象 lua垃圾回收机制 lua的GC使用 Mark And Sweep 标记清除算法 该算法设计了三种颜色标记对象(如树遍历) white 未标记(没有被使用过) gray 已标记、但关联节点未标记 black 已标记、且与之关联的节点都扫描标记了 算法过程:Mark阶段:先将内存中所有对象扫描并标记。Sweep阶段:将所有未标记(white)的对象释放 内存泄漏形式 (持续更新中) 1.全局变量 因疏忽写出的全局变量,会一直保存

catalpeak的博客 2705

Unity Lua性能优化实战:Miku-LuaProfiler深度剖析与十大高效策略

在Unity游戏开发中,脚本性能优化是保障流畅体验的核心环节,尤其当项目采用Lua热更新方案时,脚本执行效率直接关系到移动端的帧率稳定与内存控制。其原理在于通过监控Lua虚拟机的函数调用、内存分配等底层行为,将性能瓶颈可视化。这项技术的核心价值在于,它使开发者能从“黑盒猜测”转向“白盒定位”,从而实施精准优化。在应用场景上,无论是MMO手游的战斗循环,还是UI界面的频繁刷新,性能分析工具都能帮助识别如**表创建**与**字符串拼接**等高频热点。本文聚焦的Miku-LuaProfiler,正是这样一款深度集

weixin_30443731的博客 448

Lua内存泄露检测原理

lua内存泄露 首先第一点,lua中的内存泄露和我们所说的c/c++中的内存泄露本质上是不一样的。 lua中有垃圾回收机制(GC),所以理论上是不会有内存泄露的。当它进行GC的时候,会从根部开始扫描所有的对象,如果某个地方对这个对象还有引用,就不会把这个对象内存collect,这个对象就没有被GC。所以lua中的内存泄露是指那些:已经没有被使用了,但外部依然还有引用存在的对象。

u013368288的专栏 1308

GAMES101学习-第8课进行shader的初步了解

详细理解课上展示的像素着色器GLSL,以及了解了API、OpenGL、DirectX到底是什么,还有shadertoy这个网站的初步探索。

qq_41835314的博客 1917

FPGA之全数字锁相环(DPLL)

1. 数字锁相环的基本原理和组成 1.1 锁相环(PLL)的简介 锁相环最开始并不是用在数字电路中,而是模拟短路中。对于模拟电路中的锁相环,大家可以参考这篇文章稍微看一下,数字和模拟只是实现的方法不同,但是原理、步骤还是共同的。关于模拟PLL。可以参考一片文章: http://www.sohu.com/a/190569594_464086 首先在学习数字锁相环之前,我们应该先了解什么是锁相环?锁相...

DBLLLLLLLL的博客 5万+

lua C++循环引用导致的内存泄露及解决方案

本文通过一个最常见的,lua和C#/C++循环引用导致的内存泄露案例来分析原因和解决方案。

Talk is cheap. So look at my blog. 1838

FC游戏Hack实战:从零开始修改游戏数据

本文以《忍者神龟3》为例,详细介绍了从零开始进行FC游戏Hack的完整实战流程。通过使用FCEUX模拟器和调试器,结合“递减法”精准定位生命值内存地址,并利用十六进制编辑器修改关键指令,最终实现“无限生命”效果。文章旨在引导读者理解游戏数据修改的核心原理与操作技巧,重温经典的同时深入计算机程序运行机制。

weixin_28366353的博客 356

关于 Lua 内存泄漏的检测(转载)

前一阵开始和同事一起优化内存,首先是优化 Lua 内存,因为发现每次战斗完后 Lua 内存非常大,从 3M 左右在经过了10次左右的战斗后,会暴增到近 100M,很明显是有内存泄漏。然后我正式启动该工作,基本思路就是递归遍历内存中所有的数据,表,函数,协程,用户数据,查看未释放和笔误引起的全局变量泄漏;Lua 官方手册(最重要)

weixin_42333247的博客 575

Habitat-v0.1.7安装全网最详细教程(解决habitat-sim下载时网络问题)

Habitat-v0.1.7安装全网最详细教程(解决habitat-sim下载时网络问题)

shannanshouyin的博客 1326

基于ESP32-P4的低成本旋转式激光雷达系统设计

激光雷达(LiDAR)作为机器人环境感知的核心传感器,其本质是融合光学测距、机电控制与实时数据处理的嵌入式系统。理解时间飞行(ToF)原理与机械旋转耦合机制,是实现高精度点云采集的基础;而系统级误差源——如计时抖动、电机惯性、信号串扰和温漂——直接决定实际建图鲁棒性。在资源受限场景下,选用RISC-V双核MCU(如ESP32-P4)可兼顾实时控制与网络服务能力,通过硬件时间戳捕获、S型加减速轨迹规划、旋转变压器供电及双Bank OTA等工程手段,有效平衡分辨率、帧率与稳定性。本文围绕360°旋转式激光雷达的

weixin_36231030的博客 433

Lua内存泄露检测原理和weak_table弱引用

lua内存泄露 首先第一点,lua中的内存泄露和我们所说的c/c++中的内存泄露本质上是不一样的。 lua中有垃圾回收机制(GC),所以理论上是不会有内存泄露的。当它进行GC的时候,会从根部开始扫描所有的对象,如果某个地方对这个对象还有引用,就不会把这个对象内存collect,这个对象就没有被GC。所以lua中的内存泄露是指那些:已经没有被使用了,但外部依然还有引用存在的对象。 --函数中应

yxtxiaotian的专栏 8383

python 常见算法(1-50题)

常见的算法题

weixin_58470558的博客 1756

unity如何检测内存泄漏_lua内存泄漏检测工具原理及设计

然而,新增gc对象就代表内存泄漏?看下这段代码:local no_leak = {}function innocent()no_leak.a = {x = 1}no_leak.b = {y = 1}endinnocent函数每次执行都会新增两个table并持有它们,但这明显不是内存泄漏,而且这是很常见的写法。不新增gc对象就代表没内存泄漏?也不是:local local_leak = {}func...

weixin_42545664的博客 1243

Linux 完全卸载 Neovim 的方法:解决权限问题和清除残留文件

Neovim 没有被完全卸载的原因,可能是因为它是通过非官方方式(如手动编译或二进制包)安装的。对于这种情况,使用apt卸载命令无法删除这些文件。因此,需要手动删除和中的相关文件。建议在安装软件时,尽量使用包管理器(如apt)进行安装,以便以后能够方便地卸载。如果你不太熟悉 Linux 系统,避免手动操作系统目录,除非你非常清楚自己的操作。通过上述方法,你应该能够彻底卸载 Neovim 并重新安装。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 4941

Openresty原理概念篇(十)为什么 lua-resty-core 性能更高一些

Openresty(十)为什么 lua-resty-core 性能更高一些?

wzj_110的博客 778

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Lua进阶随笔

Lua性能优化 table的频繁查找,尽可能使用local变量,不要在循环中做大量表的查找,例如不要在循环中用全局函数,不要使用math.floor这种,而是将它的值提前存储在局部变量,因为即使是hash表的查找也会比较耗时; 频繁的创建新的对象,不要在循环中频繁创建新表,如a = {}这种操作等,要有缓存池的概念; 配置表的格式优化,配置表通常在游戏中占比很大,所以配表的优化也很重要; Lua Gems中给出的一个性能优化的文档,十分不错:https://www.lua.or

mozhi 841

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Lua闭包简述

Lua闭包简述 前言 最近工作上比较忙,没有太多时间来进行学习和总结,有点难受。 由于最近接触这一块比较多,所以赶紧忙里偷闲总结一篇闭包相关的笔记。 基本概念 首先我们必须知道,闭包是什么? 简而言之,闭包就是一个环境,一个能够访问外部声明的变量和方法的环境。 举个简单的小例子: local a = 100 local function f() a = 200 end 上面的代码中,f方法访问了外部的变量a,f方法就是一个闭包或者说闭包函数。 这里的变量a,也就是所谓的上值(upvalue

weixin_42186870的博客 1447

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

lua垃圾回收机制

Lua中的多数回收都是通过垃圾回收器自动完成的。Lua使用渐进式垃圾回收器,意味着垃圾回收工作会被分成很多小步,(渐进地)在程序的允许过程中执行。渐进的节奏与内存分配的速度成比例,每当分配一定量的内存,就会按比例地回收相应的内存;程序消耗内存越快,垃圾回收器尝试回收内存也就越快。 如果我们在编写程序时遵循削减和重用的原则,通常垃圾回收器不会有太多的事情要做。但是有时我们无法避免制造大量的垃圾,垃...

紫晓慕瑞的博客 1396

Lua性能优化资料整理

四、Lua调试库相关。

duxin121的博客 658

lua 内存

lua内存泄露 首先第一点,lua中的内存泄露和我们所说的c/c++中的内存泄露本质上是不一样的。lua中有垃圾回收机制(GC),所以理论上是不会有内存泄露的。当它进行GC的时候,会从根部开始扫描所有的对象,如果某个地方对这个对象还有引用,就不会把这个对象内存collect,这个对象就没有被GC。所以lua中的内存泄露是指那些:已经没有被使用了,但外部依然还有引用存在的对象。

2月7号遇见你 4532

UE4SS Lua脚本性能优化与跨版本兼容性实战指南

在游戏模组开发领域,Lua脚本因其轻量级和易集成性,常被用于扩展游戏功能。然而,当脚本与底层C++引擎频繁交互时,性能瓶颈和版本兼容性问题便成为开发者面临的核心挑战。其原理在于,每次Lua调用引擎函数都涉及虚拟机与原生代码的边界穿越,产生显著开销;同时,游戏引擎的迭代会改变内部内存布局和接口,导致硬编码的脚本失效。解决这些问题的技术价值在于,能显著提升模组的运行效率和稳定性,延长脚本生命周期,降低维护成本。应用场景广泛,尤其适用于基于UE4SS框架为《幻兽帕鲁》等Unreal Engine游戏开发复杂功能模

anchang7456的博客 371

Lua内存泄漏应对方法

由于目前正在负责的项目是一个二次开发项目,而且留给我们的代码质量实在让人无力吐槽,所以遇到了不少大大小小的坑,好在慢慢都淌过去了。最近就遇到了一个内存泄漏的问题,泄漏发生在lua里,项目代码里以前的开发团队留下了检测泄漏的代码,但也仅限于此。由于代码量庞大,所以想从逻辑上梳理清楚哪里的引用没干掉导致了内存泄漏几乎就是大海捞针。好在解决的过程比较顺利,这篇文章就来谈一谈Lua中如何解决内存泄漏的问题

This My Life - chisj 1579

modsecurity内存泄露_Modsecurity原理分析--从防御方面谈WAF的绕过(一)

0x00 背景知识一说到WAF,在我们安全工作者,或者作为普通的白帽子来说,就很头疼,因为好多时候,我们发到服务端的恶意流量都被挡掉了,于是就产生了各种绕“WAF”的话题,绕来绕去,也就无非那么多种,而且大多都是基于URLDecode的方式。虽然我的文章也会讲绕过,虽然也是那么几种,但是我会从防御的方面展示WAF规则的强大。笔者再次强调,如果你只是想学习WAF的绕过,我建议还是不要跟我的帖子了,我...

weixin_39526459的博客 289
上一篇: 利用userdata metatable和pushlightuserdata绑定c++类
下一篇: Lua的内存监测和回收
cbbbc
博客等级 码龄15年 609粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值