Lua教程之弱引用table_Lua

这次要介绍的内容比较少,就一个——弱引用table

1.无法超越人类智慧的智能——自动内存管理的缺陷

我们都知道,Lua是具备自动内存管理的,好吧,也许有些朋友不知道。

我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾的对象。

问题就出现在,什么对象才是垃圾对象,有些时候,我们很清楚某个对象是垃圾,但是,Lua却无法发现。
 
比如这样一个例子:

复制代码 代码如下:

t = {};
  
    -- 使用一个table作为t的key值
    key1 = {name = "key1"};
    t[key1] = 1;
    key1 = nil;
  
    -- 又使用一个table作为t的key值
    key2 = {name = "key2"};
    t[key2] = 1;
    key2 = nil;
  
    -- 强制进行一次垃圾收集
    collectgarbage();
  
    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end

这段代码有点复杂,智商低于250的可能会看不懂。

首先以一个table,叫做t。

然后创建一个新的table——key1,这个key1作为t的key值,给t新增了一个字段,赋值为1。

同样的,key2也作为t的一个key值。

接着,调用了collectgarbage函数,可以不管它,我们只要知道,它会让lua进行一次垃圾回收。

最后输出t的所有字段,输出结果如下:

复制代码 代码如下:

[LUA-print] key1:1
[LUA-print] key2:1

这很符合常理,也在我们的预计当中,虽然我们在给t赋值之后,key1和key2都赋值为nil了。

但是,已经添加到table中的key值是不会因此而被当做垃圾的。

换句话说,key1本身已经是nil值,但它曾经所指向的内容依然存放在t中。key2也是一样的情况。

所以我们最后还是能输出key1和key2的name字段。

2.颠覆你的认知——弱引用table

刚刚举例的只是正常情况,那么,如果我们把某个table作为另一个table的key值后,希望当table设为nil值时,另一个table的那一条字段也被删除。

应该如何实现?

这时候就要用到弱引用table了,弱引用table的实现也是利用了元表。

我们来看看下面的代码,和之前几乎一样,只是加了一句代码:

复制代码 代码如下:

 t = {};
  
    -- 给t设置一个元表,增加__mode元方法,赋值为“k”
    setmetatable(t, {__mode = "k"});
  
    -- 使用一个table作为t的key值
    key1 = {name = "key1"};
    t[key1] = 1;
    key1 = nil;
  
    -- 又使用一个table作为t的key值
    key2 = {name = "key2"};
    t[key2] = 1;
    key2 = nil;
  
    -- 强制进行一次垃圾收集
    collectgarbage();
  
    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end

留意,在t被创建后,立刻给它设置了元表,元表里有一个__mode字段,赋值为”k”字符串。

如果这个时候大家运行代码,会发现什么都没有输出,因为,t的所有字段都不存在了。

这就是弱引用table的其中一种,给table添加__mode元方法,如果这个元方法的值包含了字符串”k”,就代表这个table的key都是弱引用的。

一旦其他地方对于key值的引用取消了(设置为nil),那么,这个table里的这个字段也会被删除。
 
通俗地说,因为t的key被设置为弱引用,所以,执行t[key1] = 1后,t中确实存在这个字段。

随后,又执行了key1 = nil,此时,除了t本身以外,就没有任何地方对key1保持引用,所以t的key1字段也会被删除。

3.三种形式的弱引用

对于弱引用table,其实有三种形式:

1)key值弱引用,也就是刚刚说到的情况,只要其他地方没有对key值引用,那么,table自身的这个字段也会被删除。设置方法:setmetatable(t, {__mode = “k”});
2)value值弱引用,情况类似,只要其他地方没有对value值引用,那么,table的这个value所在的字段也会被删除。设置方法:setmetatable(t, {__mode = “v”});
3)key和value弱引用,规则一样,但是key和value都同时生效,任意一个起作用时都会导致table的字段被删除。设置方法:setmetatable(t, {__mode = “kv”});
 
当然,这里所说的被删除,是指在Lua执行垃圾回收的时候,并不一定是立刻生效的。
我们刚刚只是为了测试,而强制执行了垃圾回收。

4.结束

好了,这次的内容比较少,其实书上有蛮多关于弱引用的例子的。

关于Lua的最基础部分,到这里算是结束了。

后面的内容是一些库的介绍,以及更深入的一些内容(C和Lua间调用、自定义类型、线程、内存管理)。

接下来可能会放缓文章更新速度,因为好多库的介绍,不知道有没有必要用文章记录下来。

可能而已~

时间: 2024-11-05 23:27:42

Lua教程之弱引用table_Lua的相关文章

Lua教程(十三):弱引用table_Lua

Lua采用了基于垃圾收集的内存管理机制,因此对于程序员来说,在很多时候内存问题都将不再困扰他们.然而任何垃圾收集器都不是万能的,在有些特殊情况下,垃圾收集器是无法准确的判断是否应该将当前对象清理.这样就极有可能导致很多垃圾对象无法被释放.为了解决这一问题,就需要Lua的开发者予以一定程度上的配合.比如,当某个table对象被存放在容器中,而容器的外部不再有任何变量引用该对象,对于这样的对象,Lua的垃圾收集器是不会清理的,因为容器对象仍然引用着他.如果此时针对该容器的应用仅限于查找,而不是遍历的

Lua中的弱引用介绍_Lua

一个table的弱引用类型是通过其元素表中的__mode字段来决定的,这个字段的值应为一个字符串,如果这个字符串中包含字母'k'/'v'那么这个table 的value是弱引用,代码如下: 复制代码 代码如下: key = {}  a[key] = 1  key = {}  a[key] = 2  collectgarbage() --强制进行一次垃圾收集  for k, v in pairs(a) do      print(v)  end  结果:2 第二句复制key = {} 会覆盖第一个

java弱引用(WeakReference)和SoftReference的区别以及在android内存处理的作用

weakReference一般用来防止内存泄漏,要保证内存被VM回收  softReference的话,好像多用作来实现cache机制.   WeakReference:  弱引用对象,它们并不禁止其指示对象变得可终结,并被终结,然后被回收.弱引用最常用于实现规范化的映射.   假定垃圾回收器确定在某一时间点上某个对象是弱可到达对象.这时,它将自动清除针对此对象的所有弱引用,以及通过强引用链和软引用,可以从其到达该对象的针对任何其他弱可到达对象的所有弱引用.同时它将声明所有以前的弱可到达对象为可

当弱引用对象成为集合元素时

当我们在系统用到某些占用内存较多的大对象,且该对象并不会被频繁使用(例如缓存场景)时,若考虑性能因素,或许我们可以选择使用弱引用(WeakReference)对象.弱引用对象就像是对象之中的"无间行者",行走于"活动"与"非活动"状态之间.即使该对象存在引用,垃圾回收器仍然可以对其进行回收,这使得我们对该对象的调用始终存在一种不可预知性,除非我们通过Target属性赋给对象,以创建强引用,否则我们始终处于这种忧虑之中.这让我们常常感到左右为难,但

译文:理解Java中的弱引用

不久之前,我面试了一些求职Java高级开发工程师的应聘者.我常常会面试他们说,"你能给我介绍一些Java中得弱引用吗?",如果面试者这样说,"嗯,是不是垃圾回收有关的?",我就会基本满意了,我并不期待回答是一篇诘究本末的论文描述. 然而事与愿违,我很吃惊的发现,在将近20多个有着平均5年开发经验和高学历背景的应聘者中,居然只有两个人知道弱引用的存在,但是在这两个人之中 只有一个人真正了解这方面的知识.在面试过程中,我还尝试提示一些东西,来看看有没有人突然说一声&qu

Java中的软引用,弱引用和虚引用

在Android的图片处理中,碰到的一个非常普遍的问题便是OOM错误 为此网上也有很多例子,而在之前的一篇转载里 提到了ListView中加载图片的ImageLoader,而其中有一处,使用到了名为SoftPreference的类 这是Java中的一个类 也就是所谓的软引用 在查询了相关的资料以后 会发现SoftPreference的特性,非常适合用来处理OOM引起的问题 下面是百度文库的一篇转载: SoftReference.Weak Reference和PhantomRefrence分析和比

Java 如何有效地避免OOM:善于利用软引用和弱引用

想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引用来有效地解决程序中出现的OOM问题.下面是本文的目录大纲: 一.了解 强引用.软引用.弱引用.虚引用的概念 二.进一步理解软引用和弱引用 三.如何利用软引用和弱引用解决OOM问题 如果有不正之处,希望谅解和批评指正,不胜感激. 请尊重作者劳动成果,转载请标明原文链接:   http://www.cnblogs.com/dolphin0520/p/378

Android] Android开发优化之——使用软引用和弱引用

Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. 如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它:如果内存空间不足了,就会回收这些对象的内存.只要垃圾回收器没有回收它,该对象就可以被程序使用.软引用可用来实现内存敏感的高速缓存.软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,J

Android开发优化之——使用软引用和弱引用

Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. 如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它:如果内存空间不足了,就会回收这些对象的内存.只要垃圾回收器没有回收它,该对象就可以被程序使用.软引用可用来实现内存敏感的高速缓存.软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,J