分享好友 最新动态首页 最新动态分类 切换频道
黑科技:魔改TProto优化掉100MB的Lua内存
2024-12-27 11:33

手机的内存优化几乎是所有手机游戏都会做的事情。像iphone7,iphone8这样的机器,他的CPU非常强悍,但是内存一共就只有2G,真正能给应用使用的安全内存可能就1.1G左右。内存的限制就直接制约着游戏画面的表现,比如不能用过多的的RT,不能用大分辨率贴图,抗锯齿不能使用TAA等太多的因素。像原神这样的游戏,因为用了延迟渲染,为了保证画质更是任性的直接不支持低内存的手机。

黑科技:魔改TProto优化掉100MB的Lua内存

而Lua目前在很多游戏开发尤其是手机游戏的开发中被广泛使用,也是因为这个语言本身的特性,比如逻辑简单易修改,解释执行,支持热更等。虽然一般游戏,轻量使用Lua可能内存的占比不高,但在一些非常重度或全部代码都是写在lua的游戏中,lua的启动内存可能就轻松占用上百MB,什么都不做峰值达到300MB以上,所以对lua做内存优化,就是一个非常重要的事情。在前面有专门写一篇lua是怎样占用内存的:

如果你的游戏也是一个用lua开发的重度游戏,你可能会观察到其中有个结构TProto占用的内存非常夸张,而且这部分会常驻内存,随着项目代码量的增多而增多。那么TProto到底是什么呢?其实就是程序员写的代码,被lua的解析器编译成字节码在内存中的结构。其中code就是对应的代码,Proto是以函数或闭包为单位的。有多少个Proto就相当于是有多少个函数/闭包被加载了。所以,只要函数写的越长,单个Proto就越大,函数或文件越多Proto的数量就会越多。他的内存计算规则如下:

这里可以看到,lua在计算内存时耍了一个小聪明,只是把他认为需要计算的部分加了起来,而其中有一个占用内存比较大块的字段lineinfo,是没有被计算进内存里的

我们可以通过注释看到,这个lineinfo只是调试的时候当前字节码对应在源码中的行号信息。而Instruction本身就只有4字节,调试信息就同样占了4字节。在调试中可以发现,code的内存有多大这个lineinfo的内存就有多大,这对于游戏来说是不太合适的。当然除此外还有一些其他的调试信息,包括source以及locvars等也会占用一些内存。

所以最简单,最暴力的做法,就是全局搜索这个字段,把所有用到的地方都删掉,因为他只是调试信息不会对正常运行产生任何影响。假如你的代码在内存中有200MB,改完后你就会发现内存轻轻松松少了100MB。。。所以,到此为止,本文就可以这样简单愉快的完结撒花了

但这样做的代价,肯定就是lua代码再也看不到报错堆栈了,遇到了异常完全无法定位原因,就像C++没有符号表一样。所以下面就来提出一些方案,能够很好的解决这个问题。

也是最简单的改法。我们注意到这里代码行号使用的是int,int的上限是21亿+,但其实应该没有人能把单个lua代码文件写到20亿行的,假如我们把int改为short,那么上限是32767,对于大部分程序来说完全足够用了。

当然用到的地方,只需要改一处,就是下面加载字节码的地方,这个函数在lundump.c中。要把加载进来的int转为short,否则是放不下的。

当然这样的方案,减少的内存肯定不如直接去掉,只能减少一半,但好处就是调试信息还在。

其实再仔细观察可以发现,这里行号都是绝对行号,但其实正常的函数长度一般都不会很长,在TProto里还有个字段linedefined,记录了这个函数的开始行号,假如我们把这个字段改为相对行号,假如函数的行数都没有超过256,那理论上还可以把这个short改为uint8(unsigned char)的。在报错打堆栈的时候,再用相对行号加上linedefined即可。这样又可以节省4分之一内存,当然代价是肯定比上面更麻烦了,要在打堆栈的地方还原行号。其实理论上不加linedefined也可以正常运行,只是调试信息友好度相对差一些,只要保证所有程序员都清楚的知道规则就好。另外即使少数函数超过了256行,就只保存低位,报错时发现不对,原行号+256再多看1行就好了。

因为还剩了4分支1内存,还有没有办法再压缩一下这部分内存呢?再仔细观察,又可以发现,这里是相对行号,那么可以看到这个数组里面值其实是这样的1,1,1,2,3,3,4...要么和前一个值一样,要么是递增1的。这是因为我们写的代码都是连续的,lua在编译后生成的字节码当然也就是连续的。所以我们就可以把这个代码改为一个BitArray,每一位代表一行,如果相比前一个增加了1行,就设为1,否则为0,这样1字节就可以表示8个字节码的行号。最终内存占用就变成了原来的32分支1。当然代价是在报错或打堆栈的时候要把行号还原回去。这里搜一下lineinfo用到的地方,加上linedefined和当前位之前有多少个1就可以,这里就不再具体说怎么修改了。当然统计多少个1还是有一些快速办法的,比如UE4的数学库就提供了这样的快速函数:

如果支持SSE指令的话那会更快,比如clang下__builtin_popcountll

windows上对应的是_mm_popcnt_u64

最后,假如还是一点调试信息都不想存,又还想回复出堆栈信息,该怎么办呢?那么也可以像C++那样,把符号信息离线存成一个符号表,不跟着字节码一起打包对外发布。其实符号表完全不需要单独写,因为最终都是从lundump中读取出来的,只要保留原始字节码,对外发布的是strip后的字节码就好。我们知道lineinfo和code是一一对应的,所以报错的时候只要把code下标记录下来,然后程序员需要根据行号,到对应的符号表上找到对应的行号。当然这种方案是最麻烦的,毕竟要写工具,但肯定是效果最好的,而且安全性相对来说也是最高的,即使游戏程序遭到暴力破解后也拿不到lua的调试行号。

最新文章
高清美女写真生成神器,不可错过的AI绘图体验!
限时免费,点击体验最近超火的AI生图神器,坐拥3000美女的大男主就是你! https://ai.sohu.com/pc/generate/textToImg?_trans_=030001_yljdaimn 在这个科技迅猛发展的年代,AI正在渗透我们的生活,为我们带来诸多便利与惊喜。就拿生成美女
SEO推广优化:打造品牌,提高排名
  随着互联网的发展,越来越多的企业开始将重心转向网络营销。毕竟,在互联网时代,拥有一个良好的网站和的网络营销策略是必不可少的。而SEO(Search Engine Optimization)作为一种营销手段,被越来越多的企业所重视和采用。那么,如何
百度推广怎么优化
多维度展示多维度展示:制作图文并茂、形象直观的广告内容,便于客户理解,使产品卖点更加突出。好的创意物料能够更加吸引人眼球,为实现广告高的点击率打下扎实的基础,而广告文案创作形式上又有多种表现手法:数据分析数据分析:通过统计
第一导航——让你的上冲浪更高效
在这个信息爆炸的时代,我们每天都要面对海量的网络内容。如何在众多的网站和信息中快速找到自己需要的东西,成为了一项重要的技能。而第一导航就是为了帮助你更高效地上网冲浪而诞生的。什么是第一导航第一导航是一个集合了众多优质网站和
酒泉百度爱采购运营技巧
想要让百度等搜索引擎快速收录,实际上还要了解一下,搜索引擎是干嘛的。搜索引擎就是检索了海量的信息,让用户在搜索某些关键词时,能够快速、准确的找到结果或答案,这就是搜索引擎要做的工作。那么,要想被百度等搜索引擎收录,第一步就
越狱里面的终极BOSS是谁?
nika,捷克人,被人骗到美国做脱衣舞女,被michael所救。与michael约定好帮其越狱,因而在其入狱前一天与之结婚以便带东西进监狱给他。两人的夫妻称号有名无实,但实际上nika深深的爱上了michael,所以她才会在听到michael对sara说他对她的
生肖已解“洞百孔风行”是什么生肖动态词语
生肖字谜诗句描绘十二生肖独特韵味:洞穿岁月隐玄机百孔风行探天机。生肖轮回映乾坤鼠首潜行夜无痕。牛耕日月展宏图虎啸山林震乾坤。兔跃月影藏仙踪龙腾云汉舞风云。蛇盘洞窟藏智慧马踏飞燕踏红尘。羊踏青草春色满猴跃林间摘星辰。鸡鸣长空
晨会主持词范文【优秀20篇】
《晨会主持词范文【优秀20篇】》由白话文精心整编,希望在【爱的鼓励节拍】的写作上带给您相应的帮助与启发。伴随着新一轮的太阳冉冉升起,我们又迎来了崭新的一天,在早会开始之前,是我们的活动量管理,请各处的处长用1分钟的时光收取组
怎么看拼多多行业热搜词(拼多多现在怎么查热搜词)
发布商品的时候需要给商品取一个引人注目的标题,所以商家就要了解一下商品的热搜关键词都有哪些。那么拼多多商品热搜词该如何查看呢?下面我们就一起来了解一下吧!拼多多商品热搜词在哪里看?(商品的热搜词表明搜索人气越高搜索人数越多,
竞价区域推广费用收取明细表:公正公开,一目了然
在当今网络营销竞争激烈的市场中,竞价区域推广已成为众多企业寻求竞争优势的重要手段。为了确保公平竞争,公正公开的推广费用收取明细表是必不可少的。本文将为您介绍竞价区域推广的费用收取明细,帮助您了解整个过程。一、推广费用计算公
相关文章
推荐文章
发表评论
0评