浮点数精度丢失问题

浮点数问题,我在早前的文章聊过这个问题,感兴趣的同学点下《lua 开发防坑指南》。最近项目刚好又遇到这个问题,再细致讲下。这里以lua做说明,其他语言道理也是一样的。

在计算机中,二进制表示数字的核心是整数除 2 取余,小数乘 2 取整。小数转换为二进制时,由于精度限制,许多小数无法被精确表示,而是会变成循环二进制小数。以下是0.1的二进制表示(基于小数部分乘2取整法):

0.1 的二进制表示
整数部分1的二进制是 1。
小数部分0.1的二进制转换过程:
0.1 × 2 = 0.2 → 整数部分0
0.2 × 2 = 0.4 → 整数部分0
0.4 × 2 = 0.8 → 整数部分0
0.8 × 2 = 1.6 → 整数部分1
0.6 × 2 = 1.2 → 整数部分1
0.2 × 2 = 0.4 → 整数部分0(从此开始循环)
继续阅读浮点数精度丢失问题

skynet项目内存使用优化

Skynet/Lua 凭借其轻量易用、灵活热更、Actor并发模型的特性被广泛应用于游戏开发等场景,但 Lua 动态内存管理机制也带来了内存占用过高的挑战。

本文结合我最近对一个 skynet 项目做的内存优化分析经验,做一下分享。

1、lua 内存使用优化

1.1. 减少 lua 函数调用层数

服务端收到协议后,要经过很多次函数调用才到真正的执行函数。以手头的项目举例,服务 A 函数负责接收协议数据,收到数据后,会将协议和参数传给 B 函数处理,B 函数根据定义找到对应的模块和方法,再由 C 函数排队(一个玩家一个队列)调用 D 目录下对应的模块和函数, D 目录的模块再 require 对应的目标模块,才调用到真正的执行函数 E。最后,E 函数还会调用其他模块来完成业务逻辑。

调用层数过深的问题是,lua 要为每个过程保留过程数据,如函数地址、参数等,也就是调用栈信息(CallInfo)

建议:减少调用层级,可以使用注册回调机制
继续阅读skynet项目内存使用优化

lua table # 取长度问题

任何语言都不是完美无瑕的,在使用中都有各种问题,lua 也不例外。而 lua 使用中,绝对绕不开的一个问题就是 # 取 table 长度问题。

问题描述

先看下 # 的一些使用情况,希望引起你的困惑:

> t = {1,1,nil,1}
> #t
4
> t = {nil,nil,1,nil}
> #t
0
> t = {1,nil,nil,nil,nil,nil,nil,1}
> #t
8
> t[9] = 1
> #t
1
> t = {1,nil,nil,nil,nil,nil,nil,1,1}
> #t
9

当 table 有部分值为 nil 时,你很难清楚 # 取得的结果是什么。(如果你想知道 table 实际长度,只能遍历 table)
继续阅读lua table # 取长度问题

lua定位CPU100%问题

在开始这个话题前,说下我遇到的 skynet 进程 CPU100% 占用问题,查找 bug 的过程比较繁琐,后来想到做改进,这也是促成我写这篇文章的原因。

查到是一段 lua 代码有问题,这里截取其中出问题的代码:

-- 活动开始时间: 2033-01-01 00:00:00
local start_time = 1988121600

function start_activity()
    local now = os.time()
    local diff = now - start_time
    if diff < 0 then
        skynet.timeout((-diff)*100, start_activity)
        return
    end

    -- todo 省略活动内容
end

以上代码,通过 skynet.timeout 设置定时器,定时触发 start_activity , 看似没有问题,但是,当 skynet.timeout 第一个参数过大时,会有意想不到的收获。
继续阅读lua定位CPU100%问题

lua5.4 分代垃圾回收

前注

最近我看了 lua 5.4 分代垃圾回收的代码,网上很少讲到这块内容,于是,我写这篇文章分享一下,也当做总结。文章就以我看的 lua 5.4.4 做分析。

在进入今天的主题前,先回顾我之前写的 lua5.3 垃圾回收分析,重复的内容不再赘述。

lua 5.4 支持两种 gc 方式, 增量式 gc 和分代 gc ,默认是增量式,可以通过以下 api 切换。

切换成分代 gc:
collectgarbage "generational"
切换成增量式 gc:
collectgarbage "incremental"

提出问题

1. 增量式 gc 跟分代 gc 的对比?
2. 分代 gc 过程是怎样的?
3. 分代 gc 有哪些状态?
4. 分代 gc 怎么调优?

继续阅读lua5.4 分代垃圾回收