Linux | c&cpp | Email | github | QQ群:425043908 关注本站

itarticle.cc

01glibc下的内存管理

我们正在开发的类数据库系统有一个内存模块,出现了一个疑似”内存泄露”问题,现象如下:内存模块的内存释放以后没有归还操作系统,比如内存模块占用的内存为10GB,释放内存以后,通过TOP命令或者/proc/pid/status查看占用的内存有时仍然为10G,有时为5G,有时为3G,etc,内存释放的行为不确定。

02lua调用C++函数崩溃时,查看lua的调用栈信息

// 打印lua调用栈开始

lua_getglobal(tolua_S, "debug");

lua_getfield(tolua_S, -1, "traceback");

int iError = lua_pcall( tolua_S, //VMachine

0, //Argument Count

1, //Return Value Count

0 );

const char* sz = lua_tostring(tolua_S, -1);

// 上面的sz里面即为lua的调用栈信息,好好利用吧!

03Lua中ipairs()和pairs()的区别与使用

根据官方手册的描述,pairs会遍历表中所有的key-value值,而pairs会根据key的数值从1开始加1递增遍历对应的table[i]值,直到出现第一个不是按1递增的数值时候退出。

用pairs()遍历是[key]-[value]形式的表是随机的,跟key的哈希值有关系

但是如果是这样定义表stars的话 stars = {"Sun", "Moon", “Earth”, "Mars", "Venus"},表stars是数组的形式,是会按顺序输出的,如果 执行 stars[1] = "day",则数组会变成哈希表,再遍历时就不会顺序输出。

04游戏服务端究竟解决了什么问题?

整理下这篇文章到目前为止做了什么事情:

在文章的一开始确定了游戏服务端要解决的核心两个问题:消息的pipeline与游戏世界状态维护。

通过回顾历史的形式提出游戏服务端中最常见的需求情景:多玩家场景同步,并梳理了场景同步最适合的消息pipeline。

结合切场景的扩展需求,提出Gate这种基础设施抽象(infrastructure abstraction,简称IA)。

尝试进行高内聚、低耦合的服务划分,并总结Gate无法兼顾的消息pipeline。

针对Gate无法处理的消息pipeline(service -> service),提出新的MQ-IA,可以大大简化服务间拓扑关系。基于不同的IA与相关协议,提出更高层次的RPC协议,定义了适合.Net2.0和.Net4.5的两种异步RPC调用规范。实现了不同IA到统一规范的Adaptor。

总结了游戏中RPC应用的pattern,不同pattern如何与不同IA结合使用。同样通过回顾历史的形式引入数据服务来取代传统MMO中的Db代理进程。

结合MQ与数据服务,提出无状态服务在游戏服务端中的应用情景,展开介绍数据服务对于无状态服务的意义所在。

基于构建全局数据服务的理念,尝试实现一种多实例的、每实例内向不同服务提供原子修改操作级别一致性的数据服务。

为数据服务增加了符合需求的高可用支持。引入了zookeeper,可以让普通的服务也可以复用同样的协调者组件。


总结下出现的几种概念:

IA。包括Gate、MQ、内存db、持久化强一致性db、分布式协调器等等。不同的IA各司其职,各自只负责解决分布式系统中的一小部分问题。

RPC与Pattern。面向应用层的统一服务调用方式与规范。

Adaptor。不同的IA与相关协议到统一RPC与Pattern的适配器。

05龙之谷服务器设计

9月23日,首届“梦想·匠心”腾讯游戏开发者大会于深圳举行,在技术分论坛上,盛大游戏《龙之谷》手游技术总监李阳分享了龙之谷的服务器设计。作为《龙之谷》的手游技术负责人,李阳从事多年游戏后端开发,参与多款上线项目研发。李阳于本次论坛上分享《龙之谷》手游服务器在架构设计、灾备处理、性能优化、压力测试等方面遇到的一些问题和经验总结。

06pbc的一个陈年老BUG

这里就得提到pbc的两个feature。第一个是,如果一个optional字段的数据不存在,那么你尝试去读的时候,会返回一个默认值。这个默认值的话如果协议里不定义,整数是0,字符串是空串,而table就会生成一个新table,里面的数据全是默认值。

第二个是,如果某个optional的字段的内容是默认值,那么打包的时候会忽略。也就是说pack的结果的二进制里什么也没有。

说它是两个feature是因为,原生的protobuf是没有这回事儿的。二进制里没有,unpack的结果里去读也不会有;有数据但是是默认值,打包的二进制里也会有key-value,只是value是默认值(0或者空串),默认值一般都很小。

然后既然要自己动手,就得去读代码了。对以上features的实现,特别是读取不存在的数据的实现,并且为了高效pbc采用了默认值table的方法。什么叫默认值table呢?就是每一个protubuf的message,在第一次解包的时候,pbc的lua-binding都会生成一个默认值的table。

假设某个要读取的数据不存在,pbc的lua-binding会返回这个默认值的table。举个例子:

local msg1 = pbc.unpack('abc', buffer1)

-- 假设这时候nodata这个数据不存在

print(msg1.nodata.int_type)

-- 假设0是默认值,这里会输出0

local msg2 = pbc.unpack('abc', buffer2)

-- 如果buffer1和buffer2里都没有nodata的数据,下面两行会输出同一个table

print(msg1.nodata)

print(msg2.nodata)

那么问题就来了,这种情况,如果对解包数据是只读还好,一旦进行了写入,假设执行了msg1.nodata.int_type = 100,那么msg2.nodata.int_type也变成了100,并且以后解包的这个message的空数据里的nodata.int_type都变成了100。这也是最开始提到的那个BUG的原因。

07Lua查找表元素过程(元表、__index方法是如何工作的)

举个栗子:)

father = {

house=1

}

son = {

car=1

}

setmetatable(son, father) --把son的metatable设置为father

print(son.house)

输出的结果是nil,但如果把代码改为

father = {

house=1

}

father.__index = father -- 把father的__index方法指向自己

son = {

car=1

}

setmetatable(son, father)

print(son.house)

输出的结果为1,符合预期

08检测Lua中临时对象造成的内存增长

创建临时对象,比如临时表、临时闭包,向table里加key value,都会使lua虚拟机内存增加,虽然可被gc掉但会造成更频繁的gc,gc速度没分配速度快的话进程容易挂。问题就是如何自动化的找到分配临时对象内存的lua代码,造成内存增长的情况很多怎么找呢

09Lua math string库

Lua math string 库 http://cloudwu.github.io/lua53doc/contents.html 《Lua5.3参考手册》

10pbc默认值问题

这里就得提到pbc的两个feature。第一个是,如果一个optional字段的数据不存在,那么你尝试去读的时候,会返回一个默认值。这个默认值的话如果协议里不定义,整数是0,字符串是空串,而table就会生成一个新table,里面的数据全是默认值。

第二个是,如果某个optional的字段的内容是默认值,那么打包的时候会忽略。也就是说pack的结果的二进制里什么也没有。

11浅析Lua中table的遍历和删除

在Lua中,最最核心的数据结构就是表.表不仅可用作数组,还可以用作字典.Lua面向对象的实现也是用表实现的.这里主要讨论表的遍历和删除操作

12Lua非常有用的工具——递归打印表数据

在Lua中,我认为最最核心的数据结构就是表。表不仅可用作数组,还可以用作字典。Lua面向对象的实现也是用表实现的

我的名片

网名:丰果 | Ranger

职业:游戏开发

现居:上海市

Email:86668082@qq.com




站点信息

  • 建站时间:2016-04-01
  • 文章统计:728条
  • 文章评论:82条
  • QQ群二维码:扫描二维码,互相交流