首页 > 代码库 > Lua程序设计 第17章 弱引用笔记
Lua程序设计 第17章 弱引用笔记
鉴于之前我对lua的评价,在此需要修改了一下我的言论:游戏开发语言工作中,最成熟的客户端开发组合:C/C++、Lua/C#、assembly汇编。C/C++系列用于完成游戏引擎框架,汇编用于优化,Lua负责游戏逻辑。在全局上满足了性能、可读性、变化性的需求。因为我选的是引擎方向,实际上只能吃透C/C++系列我才可能获得引擎 职位。另外推荐一本书《游戏引擎框架》-叶劲峰翻译的那本,并没有csdn某人读后感言“引擎水真深”的感觉。这本书写得好,可是那个废人却在叶劲峰的专访中说这么本书很难,一定吓退了一些新人或至少泼了冷水。
lua的弱引用主要是实现一个类似于引用计数功能,目的还是用于管理内存。我怀疑table的引用管理就是建立在弱引用的基础上。通过设置一个table的__mode="kv"启用弱引用。
在弱引用就类似于引用计数为0的状态,当调用垃圾回收collectgarbage()会清理掉引用计算为0(类比,目前我没有看到源码的垃圾回收实现)。,每次执行赋值操作,都会在该地址指向的对象执行+1操作,而数值、bool、字符串,应该作为常量。有个问题这个三种类型数据的清理时怎么实现的?待续
首先知道table是个对象,平时引用式赋值都是地址外加引用技术。看看table和node源码定义就明白了
typedef struct Table { CommonHeader; lu_byte flags; /* 1<<p means tagmethod(p) is not present */ lu_byte lsizenode; /* log2 of size of `node' array */ struct Table *metatable; TValue *array; /* array part */ Node *node; Node *lastfree; /* any free position is before this position */ GCObject *gclist; int sizearray; /* size of `array' array */ } Table;
数组部分:
** Union of all Lua values */ typedef union { GCObject *gc; void *p; lua_Number n; int b; } Value;//这是非常经典的数据结构,可以将其名之为Lua数据原子,用来完成绝大部分数据存储 标注1 /* ** Tagged Values */ #define TValuefields Value value; int tt //tt是用来记录当前数据域存储的数据类型 typedef struct lua_TValue { TValuefields; } TValue;
键值对部分:
typedef union TKey { struct { TValuefields; struct Node *next; /* for chaining */ } nk; TValue tvk; } TKey; typedef struct Node { TValue i_val; TKey i_key; } Node;
table中的数据只要分为三大部分:metatable,用于管理当前类的操作定义;array明显是数组部分;Node则是常用键值对。待续,得去看看lua用了什么样的哈希函数
标注1 先贴一份引用博客,值得阅读点击打开链接
涉及到弱引用就得联系到内存存储相关。number、bool、string等得清理时交给了C的机制去管理,是C编译器实现的那套,其余使用了数据原子Value的数据对象,都符合弱引用的使用环境。
弱引用有两大已说明的用途:纯数据缓存(cache、备忘录),tabel等对象在命名空间中的管理(对象属性)。
纯数据缓存:比如loadString、loadFile、或如书中提及rgb数据缓存,这样子可以在一个子区域共享同类数据,减少重复操作。在缓存区中保存只能是弱引用,当外部的强引用全部置为nil时只剩下缓存区的弱引用,则会在下次collectgarbage调用时清理掉这条缓存。
对象属性:因为使用了 Closure相关的技术,同一个table可能处于不同的语法域lexical Scoping,必须要用额外的信息记录这个table的可访问路径。这个属性不属于原table,也不是纯数据的缓存,按照书中说的,应该是在词法域中增加了当前可访问区域的table记录,这个时候就就得使用外部弱引用了。
Lua程序设计 第17章 弱引用笔记