lua5.3 垃圾回收分析

前注

最近我一直在看lua gc,阶段性做一下总结。网上很多文章没讲明白,我也当弥补下这个问题。文章以我看的lua 5.3.6做分析。

lua 垃圾回收发展历程

5.0 及以前使用的是双色标记清除法,gc 过程会停止主程序执行,直到 gc 完成;
5.1 实现了增量式 gc,采用三色标记法,gc 过程分多步,与主程序交替执行;
5.2 实现了分代 gc,实际效果不理想;
5.3 移除了分代 gc;
5.4 重新实现了分代 gc

两种标记清除算法

标记清除算法,就是遍历所有对象,将还在使用的对象打上标记,遍历完成后,没有标记的对象就是垃圾对象,要清理掉。

所以,系统至少需要记录两个数据集合,一个是所有的对象集合,一个是还在使用的对象集合。在 lua 中,还在使用的对象集合包括了全局变量、 栈中对象、处于激活状态的协程等。
继续阅读lua5.3 垃圾回收分析

lua table怎么检查数据变了

为了缓解数据库压力,数据会缓存在lua table,满足频繁读写需求,再定时检查,发现数据变了则落地。

问题来了,lua table怎么检查数据变了?

table检查数据变了

答案很简单,使用 metatable,这里贴一个简单的例子。

-- db数据
db = {openid="openid_123", token="token_123"}

-- 缓存
cache = {}

setmetatable(cache, {
	__index = function(t, k)
		return db[k]
	end,
	__newindex = function(t, k, v)
		if k ~= "__dirty" then
			db.__dirty = true
		end
		db[k] = v
	end,
	__pairs = function(t, k)
		return next, db, k
	end,
})


for k, v in pairs(cache) do
	print(k, v)
end

cache.__dirty = nil
print("cache.__dirty", cache.__dirty)

cache.token = "token_456"
print("cache.__dirty", cache.__dirty)


执行结果如下:

> dofile("test.lua")
token   token_123
openid  openid_123
cache.__dirty      nil
cache.__dirty      true

问题到这里就结束了。

接下来,我们再提出一个问题,lua table如何检查子项为table的数据变了?
继续阅读lua table怎么检查数据变了

浅析lua异常捕获处理机制

原文 2015-10-19 23:13:06 发表于 CSDN,这里对以前写的文章做下收录。

异常捕获是高级语言的一大特性,通过对异常的捕获和处理,可以有效提高系统的稳定性和健壮性。无论再怎样改进代码,都不可避免出现一些异常,例如文件io错误、网络错误、内存错误等等,就要求编码对错误进行捕获,同时打印日志以便开发人员跟进问题的处理。当然,lua也提供了接口用于捕获运行时异常。

lua异常捕获函数

lua有两个函数可用于捕获异常: pcall 和 xpcall,这两个函数很类似,都会在保护模式下执行函数,效果类似try-catch,可捕获并处理异常。
两个函数的原型如下:

pcall (func [, arg1, ···])
xpcall (func, errfunc [, arg1, ···])

继续阅读浅析lua异常捕获处理机制

lua 异步HTTPS并发请求库

原文 2017-03-21 19:19:54 发表于 CSDN,这里对以前写的文章做下收录。

项目使用skynet框架,这个框架主要用lua写逻辑,但缺乏对HTTPS支持,所以我利用一点时间写了lua模块,支持异步HTTPS请求,文章这里讲述HTTPS相关知识,如何接入openssl请求HTTPS数据,同时也分享了lua模块给大家参考。(注:新版本已支持)

继续阅读lua 异步HTTPS并发请求库

lua匹配UTF-8中文汉字

lua5.3虽然支持utf-8,但是自带的string库不支持汉字的处理,而且lua的正则实现也比较鸡肋,很难匹配中文。所以文章讨论UTF-8字符集,中文汉字的表示方法,然后说明lua如何匹配UTF-8中文汉字。

初识UTF-8

UTF-8是Unicode的一种实现,是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。

继续阅读lua匹配UTF-8中文汉字

skynet 热更新 lua 代码

原文 2016-12-30 16:18:15 发表于 CSDN,这里对以前写的文章做下收录。

skynet开发太多数情况下只是写lua代码,很少用写c,这一定程度上提高了项目的开发效率。lua虽然没有C高效,但开发复杂业务却是非常便捷,而且lua支持热更。skynet有两种方法热更新lua代码,clearcache和inject,文章分别对这两种方法做说明。

继续阅读skynet 热更新 lua 代码