Lua的内存监测和回收

Lua内存是自动收集的, 这点跟Java类似, 不被任何对象或全局变量引用的数据,将被首先标记为回收,不需要开发者做任何事情.但是,正如Java也会有内存泄露一样,
Lua也会有, 只不过,跟C++的不同,它是由于代码执行所装载的资源,并没有被彻底销毁而导致,其中,最臭名昭著的就是不小心把局部变量声明成了全局变量(忘了加local修饰符)。 类似这样造成的内存泄露, 跟任何其他语言的内存泄露一样,容易产生,却难以察觉, 给开发的应用带来潜在的很大隐患.

那么, 有没有一些有效的解决办法, 来解决这个这个隐患呢, 答案就是collectgarbage.
collectgarbage就是开放给Lua开发人员, 用于监听Lua的内存使用情况(collectgarbage("count")), 同时,它还提供了collectgarbage("collect"),允许在适当的时候进行显式的回收.

现在,通过测试代码来看看,如何玩转collectgarbage.

首先,为了有明显的对比, 先来看没有产生泄露的情况, 运行以下的test1(代码如下):

运行结果如下:


 这里看到, 被local 声明的colen加了5000数组,
test1调用后, 内存增加了大概300K(25906K-25620K).

现在,我们来做内存回收(调用mem函数, 代码如下):


 运行结果:


( 为了保证内存的稳定,以上注意mem被调用了多次, 再第2次, 可以看到内存开始下降, 最后,大概在25618K稳定下来)

好了, 从最初的25620K, 到回收后的25618K, 两者并没有发生变化(还少了2K,嘿嘿,
这应该是误差了), 也就是说,函数test1的执行,并没有产生无法回收的内存,没有泄露出现.

好了,现在运行有泄露的test2(代码如下), test2跟test1相比,只有一处不同:就是colen被误声明为全局:


结果:

也就是说,内存也在25906K,跟test1几乎是相等, 好了,现在再调用回收(mem)函数,产生结果如下


 为了保证函数回收被执行,这次,总共调用了7次mem函数(看以上打印行数), 那么,从上面的结果我们看, 很不幸, 从第1次,到最后第7次, 内存都还是稳定在25905K左右, 也就是说, 跟调用test2前相比,即使Lua进行了内存回收, 内存却不会将下来 看来, 这300K(25906K-25620K)内存, 由于已放到了全局函数中,是永远没有机会被回收到了!

总结一: 如何监测Lua的编程产生内存泄露:

1.       针对会产生泄露的函数,先调用collectgarbage("count"),取得最初的内存使用

2.       函数调用后,
collectgarbage("collect")进行收集, 并使用collectgarbage("count")再取得当前内存, 最后记录两次的使用差

3.       从test1的收集可看到,
collectgarbage("collect")被调用,并不保证一次成功, 所以, 大可以调用多次

总结二: 如何避免Lua应用中出现的内存使用过大行为:

1.       当然是代码实现不出现泄露, (废话*&%$()

2.       在测试中,其实还发现,
Lua中被分配的内存,其实并不会自动回收(个人估计要么就是Lua虚拟机没有做这个事情,要么就是回收的时机是在C层), 所以, 为了避免内存过大, 应用的运行时,可能需要定期的(调用collectgarbage("collect"),又或者collectgarbage("step"))进行显式回收。

(原文转载来自http://blog.csdn.net/henren555/article/details/17579153 )

Lua的内存监测和回收,布布扣,bubuko.com

时间: 2024-12-17 09:44:35

Lua的内存监测和回收的相关文章

lua内存监测和回收

以下来自书籍<Cocos2d-x之Lua核心编程> 1.----------------------------------------- 若想查看程序当前的内存占用情况,可以使用Lua提供的collectgarbage.collectgarbage是Lua内部的垃圾回收模块对外提供的接口,可以用来监控或改变垃圾回收器的默认行为. 下面是一个collectgarbage使用的例子 print(collectgarbage("count")) local test = {}

内存监测工具 DDMS --&gt; Heap

无论怎么小心,想完全避免bad code是不可能的,此时就需要一些工具来帮助我们检查代码中是否存在会造成内存泄漏的地方.Android tools中的DDMS就带有一个很不错的内存监测工具Heap(这里我使用eclipse的ADT插件,并以真机为例,在模拟器中的情况类似). 用 Heap监测应用进程使用内存情况的步骤如下: 1. 启动eclipse后,切换到DDMS透视图,并确认Devices视图.Heap视图都是打开的: 2. 将手机通过USB链接至电脑,链接时需要确认手机是处于"USB调试&

C基础 内存越界和内存监测的简单处理

引言 突然感觉要出去走走了, 醒了后 刷完牙就在联系coding, 不知不觉到了 黄昏. 看看天, 打开灯. 又感觉到了 夜夜夜夜 . 13年到北京务工, 遇到一批批NB的同龄人物. 一块工作, 一块喜欢锻炼, 一块默默的学习. 从他(她)们身上发现一个事实. 假如我们一样聪明, 当你抱怨自己为什么努力了, 确还是 这么水的时候  ;   其实他(她)们在拼命. 而你只是在努力 , 假如我们不一样聪明, 如果还不能开挂,  那会是怎么样精彩 x x x x. 前言  -  内存越界处理 我们先看

Android 中使用内存监测工具Heap,及内存分析工具 MAT

无论怎么小心,想完全避免bad code是不可能的,此时就需要一些工具来帮助我们检查代码中是否存在会造成内存泄漏的地方.Android tools中的DDMS就带有一个很不错的内存监测工具Heap(这里我使用eclipse的ADT插件,并以真机为例,在模拟器中的情况类似).用Heap监测应用进程使用内存情况的步骤如下: 1. 启动eclipse后,切换到DDMS透视图,并确认Devices视图.Heap视图都是打开的: 2. 将手机通过USB链接至电脑,链接时需要确认手机是处于“USB调试”模式

JVM堆内存监测的一种方式,性能调优依旧任重道远

上月,由极客邦.InfoQ和听云联合主办2016 APMCon中国应用性能管理大会圆满落下帷幕.会上,Java冠军Martijn Verburg进行了一场Java and the Machine的分享,讨论了为什么数据分析至关重要.他有着十多年Java经验,目前是创业公司jClarity的CEO,jClarity是一款采用统计和机器学习来探究性能问题根源的方案.会后,InfoQ还专访Martijn以进一步了解沟通. JVM堆内存及一种监测方式 在讨论Martijn的团队如何进行堆内存监测之前,我

Android 内存监测工具 DDMS

Android 内存监测工具 DDMS --> Heap 2011年06月02日 11:18:00 幻影浪子 阅读数:72529 用 Heap监测应用进程使用内存情况的步骤如下:1. 启动eclipse后,切换到DDMS透视图,并确认Devices视图.Heap视图都是打开的:2. 将手机通过USB链接至电脑,链接时需要确认手机是处于“USB调试”模式,而不是作为“Mass Storage”:3. 链接成功后,在DDMS的Devices视图中将会显示手机设备的序列号,以及设备中正在运行的部分进程

最简单例子图解JVM内存分配和回收

一.简介 JVM采用分代垃圾回收.在JVM的内存空间中把堆空间分为年老代和年轻代.将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象.年轻代中又被分为Eden区(圣经中的伊甸园).和两个Survivor区.新的对象分配是首先放在Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次收集仍然存活的,就会被转移到年老区. 简单讲,就是生命期短的对象放在一起,将少数生命期长的对象放在一起,分别采用不同的回收

Java深入 - Java 内存分配和回收机制-转

Java的GC机制是自动进行的,和c语言有些区别需要程序员自己保证内存的使用和回收. Java的内存分配和回收也主要在Java的堆上进行的,Java的堆中存储了大量的对象实例,所以Java的堆也叫GC堆. Java在垃圾收集的过程中,主要用到了分代收集算法,我会先讲一下常用垃圾收集算法. 常用垃圾收集算法 1. 标记-清除算法 这种垃圾收集算法思路非常简单,主要是首先标记出所有需要回收的对象,然后回收所有需要回收的对象. 但是有一个明显的缺点,采用这种算法之后会发现内存块回收之后就不连续了,这就

转!!Java虚拟机堆的内存分配和回收

Java内存分配和回收,主要就是指java堆的内存分配和回收.java堆一般分为2个大的区域,一块是新生代,一块是老年代.在新生代中又划分了3块区域,一块eden区域,两块surviver区域.一般称为from surviver和to surviver.这些区域的大小可以自己指定.比如:(-Xms20M 表示可用堆内存大小:-Xmx40M 表示最大堆内存,在堆内存大小不够时,会扩展到最大堆内存:-Xmn10M 表示新生代内存大小). 新生代中的对象会在eden区域分配,然后eden区域的内存不够