您的位置:首页 > 编程语言 > Lua

读书笔记《Lua设计与实现》 了解Lua底层

2017-10-08 15:13 288 查看
孙广东  2017.10.8http://blog.csdn.NET/u010019717

十一抽时间看了这本书。
        还记得第一次接触Lua 是在2014年7月份, 当时还是在长春实习(Cocos Lua), 接触了一个多月就来北京开始了Unity

我是很喜欢看纸质书的,不太喜欢看电子书。 作者说这是第一本揭示Lua实现原理的图书。   这个历史就不了解了, 但是以前收藏过
《lua源码分析》  https://wenku.baidu.com/view/c96a0e1055270722192ef772.html,         《readinglua云风的Lua源码赏析》.pdf    都是都是很早就有电子版本的。
说的有点跑偏,   要了解这些底层,还是最好有C/C++基础的好(专业会学到)。 大学还是学过编译原理,汇编语言的,  总之看完这本书还是对Lua有一个全新的认识。

Lua虚拟机 和 GC算法

1、 Java,  .Net 都是基于栈的虚拟机。  Lua是使用基于  寄存器的虚拟机。
2、 Lua 最多支持2^6 - 1 = 63 个指令。  这些指令类似于汇编指令。 
3、无论函数怎么执行,有多少函数,最终他们引用到的栈都是当前Lua虚拟机的栈 (这个栈在函数调用和 返回值的时候很重要)
4、 Lua词法
当时学习编译原理,  对一个语言进行解析一般是两遍遍历的过程: 第一遍解析源代码并生成抽象语法树(AST), 第二遍在将抽象语法树翻译为字节码。
但是Lua只进行一遍扫描。  这里就要提到  “递归下降法”  进行解析了。 
5、GC算法
       之前了解过 .Net 的GC.  《《读书笔记》C#/.Net 的托管堆和垃圾回收》   
书中也提到 引用计数标记清除算法
提到Lua 5.0 使用的是   双色标记清除算法,       提到Java , .Net 都存在的一个问题就是在GC过程中,程序必须暂停下来, 不能进行其他操作。   但是在Lua 5.1 开始解决了这个问题。  使用了 三色增量标记清除算法

跟踪指令解析和执行过程中常用的两个手段。
1) GDB调试
2) ChunkSpy  (LUA脚本动态反编译代码  http://chunkspy.luaforge.net/ ).   可以得到函数信息 指令,局部变量,常量等, 多层函数的嵌套关系

环境与模块

          看了这部分对作用域,  Lua热更新有帮助.
几个与环境相关的特殊变量----------Global表(G表)、 env表、 registry表以及 UpValue


字符串

        字符串在接触到的所有计算机语言中都是不可变的。  这是一个面试题啊, 为什么这样设计?
大概是这三点吧:
1. 字符串常量池的需要
字符串常量池(String pool, String intern pool, String保留池) 是Java堆内存中一个特殊的存储区域, 当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。    (一种享元模式)
2. 允许String对象缓存HashCode
Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。
       字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码. 在String类的定义中有如下代码:
3. 安全性
       String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等, 假若String不是固定不变的,将会引起各种安全隐患。

在Lua可以记住以下几点:
1)在Lua虚拟机中存在一个全局的数据区,用来存放当前系统中的所有字符串
2)同一个字符串数据,在Lua虚拟机中只可能有一份副本。
3)变量存放的仅是字符串的引用,而不是实际内容。
4)字符串比较实际上比较的是 字符串散列值(整数)

这里可以多提一嘴,就是 Golang的中的字符串, 因为当时学的时候  印象很深, Golang的string的所有操作的索引都是字符串的字节索引不是字符索引!!!

          表在Lua中太重要了, Lua使用表来统一表示Lua中的一切数据,  Lua的面向对象也是基于表实现的。
Lua的表分为数组部分 和 散列表部分。 其中数组部分的索引是从1开始的。
        这里就有一个问题了,   当我们以一个整数作为键值的数据写入Lua表时,并不确定是写入了数组还是散列表中???
自己看吧

在使用表时需要注意以下事项:
1)尽量不要将一个表混用数组和散列桶部分,即一个表最好只存放一类数据。
2)尽量避免进行重新散列操作, 因为重新散列操作的代价极大。  可以通过预分配,只使用数组部分等策略规避这个Lua解释器背后的动作, 能提升不少效率。

在 6.3 章节中,  有介绍表相关的操作指令
特别是介绍  “元表的实现原理” 和 面向对象!

Lua 源代码基本上都是采用纯 C 编写。
           想起大学时学习C语言,当时也并没有注意到   union  联合类型应用居然这么重要。  只知道struct结构体 复合数据很重要。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: