当前位置: 首页 > news >正文

【lua】lua内存优化记录

这边有一个Unity项目用的tolua, 游戏运行后手机上lua内存占用 基本要到 189M, 之前峰值有200多。

优化点1  加快gc频度:

用uwa抓取的lua内存, 和unity的mono很像,内存会先涨 然后突然gc一下,降下来。 这样内存峰值就会比较高,再加上游戏里其他内存占用多, 3G的ios内存吃紧很不友好,容易闪退。
所以一个方法 调了lua gc的参数, 让其加快了gc频率, 由于lua这边是增量式GC的,所以gc频率高了 也没啥卡顿。 最后性能测试 发现lua 游戏里内存占用基本是 一条直线了。

参数是这么设的, 另外一个项目的lua也是这么设的,网上找到的一些例子也设了这个参数:

    collectgarbage("setpause",100)      --表示当收集器在总使用内存数量达到上次垃圾收集时的(100/100)一倍时再开启新的收集周期。 (默认200)collectgarbage("setstepmul",5000)   --表示垃圾收集器的运行速度是内存分配的50(5000/100)倍,如果此值小于100可能会导致垃圾回收不能形成完整的周期。 (默认200)collectgarbage("restart")

之前是默认值,回收频率比较低。


 

优化点2 去掉了因require路径 / 和 .的混用造成的重复加载:


参考我另外一篇文章单独说了这个问题。
发现契机是这样的, 这边点开始游戏 会初始化预处理很多数值表(原因就是 require 来 require 去, 引用关系嵌套 导致很多不一定用的表也加载了。  因为登录游戏后服务器发数据过来 必须把有的模块初始化好, 这个也是个优化点,暂时还没去处理),  卡顿很久体验不好。   所以想到刚进游戏 在登录界面等待没事做时可以 分帧加载必须的数值表。  减少一次性的卡顿。

但跟踪发现 好像优化不大,而且好多表都加载2次。
才发现 require "data/xxxx" require "data.xxxx" 在真机上会加载2次 (用的库没改好)。

简单优化方案,入口lua最开头,重写 require 把 传进来的路径 把/替换成的.

实际一跑,发现卡顿时间表少了, 内存还减少了35M左右。

优化点3 数值表lua里内存精简:


一开始看了这篇文章:
Lua性能优化(一):Lua内存优化 - 知乎
里面提到了这篇文章:
Lua配置表存储优化方案 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技

这边项目的策划数值表是导出成protobuf的二进制格式,然后加载到内存里。方便前后端解析(因为协议都是用Protobuf)。
但项目里数值后期太多, 大头都是数值表,所以优化数值表可以省很多内存:

优化方法A    就是前面有提到的 把字段名优化掉 (这个项目很早之前就实现过了),   
 把解析出来的数据 每行字段值 按[1] [2] ……[n] 索引存放, 代码请求时 用了一个meta table,里面记录了 表的所有字段名及对应的索引 (从.pbc文件里解析 google.protobuf.FileDescriptorSet 得到的)

	local dataMetatable = {}dataMetatable.keys = {}local t_pbc = protobuf.decode("google.protobuf.FileDescriptorSet", pbcBuff)local proto = t_pbc.file[1]for _,v in ipairs(proto.message_type[1].field) dodataMetatable.keys[v.name] = v.numberenddataMetatable.__index = function(t, k)local v = rawget(t, dataMetatable.keys[k])return vend

这样确实省下二三十M内存吧(数值不一定准)。    解析表会稍慢些。

优化方案B  每行数据按需加载
这个方案思路本来挺好的, 当时也是为了节省C#那边的mono内存。  
把数值文件,预处理一下,把每行数据的各自序列化后按顺序存放成一个二进制文件,  另外还要生成一个索引对照文件,里面记录了某个key 在数值表的起止位置。 
这样数值表很多暂时用不到的数据就不用加载进来。 省下很多内存。 getbykey时,找一下发现内存里没有,则用流方式去文件里读取数据,然后单行反序列化下就行了。  (只不过索引文件也会占一部分额外内存放在内存里面)

实际项目到了后期,发现内存没省多少,进加载也特别卡了。    因为很多数值表 数据需要全部遍历预处理一下一些字段, 造成不少表还是全部读取了,反而没有优化,变更卡更占内存。   也没有不用了 回收的机制。 
(这个可以继续规范优化,比如个别表全部加载方式,个别表按需加载,  再实现长久不用的数据或表释放掉……)


优化方案C 每个数值表设一张默认值表

就是前面uwa文章里提到的,一般数值表有很多字段完全一样,没必要重复存放。(这边项目后期确实很多字段虽然看起来用着但都默认填一样,基本是废的,但还占用内存)
这样就可以 把一些数据很多的表,统计一下每个字段的默认值, 
导表或者解析表数据存到内存时, 发现字段和默认值一样的,就不要导出或者存到内存里,直接置空就行了:



这边是这样实现的在 方案A的基础上做了调整, metatable里加了一个default表, 
__index时,如果key取到数据为nil,则从default表里取:

		local data_name = proto.message_type[1].name -- 数值表名dataMetatable.default = InitDataDefault.get_data_default(data_name)for _,v in ipairs(proto.message_type[1].field) dodataMetatable.keys[v.name] = v.numberenddataMetatable.__index = function(t, k)local v = rawget(t, dataMetatable.keys[k])if nil == v and dataMetatable.default thenv = dataMetatable.default[k];endreturn vend


default表的结构类似这样:

针对几个大表处理, lua gc后,内存降了有40多M,  只不过加载时间可能会变长些,所以目前只是在IOS小内存设备上开了这个处理。  

内存优化量仅供参考。 具体还是看数值表的复杂情况和量级。



附带其他几个lua 优化的文章:
Lua性能优化技巧_lua 性能优化-CSDN博客

https://www.cnblogs.com/marcher/p/16866981.html

相关文章:

【lua】lua内存优化记录

这边有一个Unity项目用的tolua, 游戏运行后手机上lua内存占用 基本要到 189M, 之前峰值有200多。 优化点1 加快gc频度: 用uwa抓取的lua内存, 和unity的mono很像,内存会先涨 然后突然gc一下,降下来。 这样…...

紫光展锐T618_4G安卓核心板方案定制

紫光展锐T618核心板是一款采用纯国产化方案的高性能产品,搭载了开放的智能Android操作系统,并集成了4G网络,支持2.5G5G双频WIFI、蓝牙近距离无线传输技术以及GNSS无线定位技术。 展锐T618核心板应用旗舰级 DynamlQ架构 12nm 制程工艺&#x…...

Redis 群集部署

1.关系型数据库 关系型数据库是一个结构化的数据库,创建在关系模型基础上,-般面向记录。它借助于集合代数等数学概念和方法来处理数据库中的数据。关系模型指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织。现实世界中…...

WPF中如何设置自定义控件(二)

前一篇文章中简要讲解了圆角按钮、圆形按钮的使用,以及在windows.resource和app.resource中设置圆角或圆形按钮的样式。 这篇主要讲解Polygon(多边形)、Ellipse(椭圆)、Path(路径)这三个内容。 Polygon 我们先看一下的源码: namespace System.Windows.Shapes { pu…...

【C++】每周一题——2024.3.3

题目 Cpp 【问题描述】 字符环(来源:NOI题库)。有两个由字符构成的环,请写一个程序,计算这两个字符环上最长公共字符串的长度。例如,字符串“ABCEFAGADEGKABUVKLM”的首尾连在一起,构成一个环&a…...

5G网络架构与组网部署01--5G网络架构的演进趋势

目录 1. 5G网络架构的演进趋势 1.1 5G移动通信系统整体架构 1.2 4G移动通信系统整体架构 1.3 4G与5G移动通信系统整体架构对比 1.4 核心网架构演进 1.5 无线接入网演进 1. 整体架构组成:接入网,核心网 2. 5G网络接入网和核心网对应的网元&#xff…...

2023全球软件开发大会-上海站:探索技术前沿,共筑未来软件生态(附大会核心PPT下载)

随着信息技术的迅猛发展,全球软件开发大会(QCon)已成为软件行业最具影响力的年度盛会之一。2023年,QCon再次来到上海,汇聚了众多业界精英、技术领袖和开发者,共同探讨软件开发的最新趋势和实践。 一、大会…...

C#插入排序算法

插入排序实现原理 插入排序算法是一种简单、直观的排序算法,其原理是将一个待排序的元素逐个地插入到已经排好序的部分中。 具体实现步骤如下 首先咱们假设数组长度为n,从第二个元素开始,将当前元素存储在临时变量temp中。 从当前元素的前一…...

快速搭建Vue前端框架

快速搭建Vue前端框架 安装Vue Vue官方安装过程:https://cli.vuejs.org/zh/guide/installation.html 二.创建Vue工程 2.2 安装淘宝镜像 安装淘宝镜像(会让你安装Vue的速度加快): npm config set registry https://registry.npm.taobao.or…...

TS中private和protected的区别

在 TypeScript 中,private 和 protected 是两种访问修饰符,用于限制类成员(如属性、方法等)的可见性和可访问性。它们的主要区别在于访问权限的宽松程度。 1. private 当一个类的成员被标记为 private 时,它只能在该…...

虚拟机Hyper-V操作记录

问题1:安装Hyper-V,虚拟机监控程序无法打钩,提示该固件的虚拟化支持被禁用 主板型号:华硕ASUS ROG STRIX Z390-E GAMING 解决方法:进入BIOS,Advanced/CPU Configuration/Intel(VMX) Virtualization Technol…...

90. 子集 II(力扣LeetCode)

文章目录 90. 子集 II题目描述回溯算法 90. 子集 II 题目描述 给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 …...

202435读书笔记|《半小时漫画中国史》——读点经济学与历史,生活更美好,趣味烧脑土地制度、商鞅变法、华丽丽的丝绸之路这里都有

202435读书笔记|《半小时漫画中国史》——读点经济学与历史,生活更美好,趣味烧脑土地制度、商鞅变法、华丽丽的丝绸之路这里都有 1. 土地政策、度量衡及税收2. 商鞅变法3. 西汉经济4. 西汉盐铁大辩论5. 西汉丝绸之路 《半小时漫画中国史:经济…...

2023下半年主品牌锋芒依旧,江南布衣打破既定天花板?

在过去的2023年里,服装板块令人意外的领涨消费大盘,国家统计局数据显示,上半年服装零售额同比增长12.8%,远超商品零售大盘的增速6.8%。 整体表现强劲的同时,“局部”表现是否也尽如人意。近日,作为时尚服装…...

Gitlab: PHP项目CI/CD实践

目录 1 说明 2 CI/CD 2.1 部署方式一:增量部署 2.1.1 目标服务器准备 2.2.2 Gitlab及Envoy脚本 2.2 部署方式二:镜像构建与部署 2.2.1 推送到私有化容器仓库 准备工作 脚本 要点 2.2.2 推送到hub.docker.com 准备工作 脚本 3 参考&#x…...

c语言游戏实战(10):坤坤的篮球回避秀

前言: 这款简易版的球球大作战是博主耗时两天半完成的,玩家需要控制坤坤在游戏界面上移动,来躲避游戏界面上方不断掉下来的篮球。本游戏使用C语言和easyx图形库编写,旨在帮助初学者了解游戏开发的基本概念和技巧。 在开始编写代…...

初学arp欺骗

首先准备一台靶机这里用虚拟机的win10 已知网关与ip地址(怕误伤) 现在返回kali从头开始 首先探测自己的网关 然后扫内网存活的ip 发现有3台 用nmap扫一下是哪几台 成功发现我们虚拟机的ip 现在虚拟机可以正常访问网络 接下来直接开梭 ip网关 返回虚拟机…...

ftp几个常见错误问题及解决办法

1、无法上传网页,FTP故障-提示“无法连接服务器”错误。 问题出现原因:FTP客户端程序设置问题,客户上网线路问题,ftp服务器端问题。 处理方法:建议客户使用CUTPFTP软件来上传客户的网页,在“F…...

鸿蒙App开发新思路:小程序转App

国家与国家之间错综复杂,在谷歌的安卓操作系统“断供”后,鸿蒙系统的市场化&独立化的道路便显而易见了。 2024年1月18日,华为宣布,不再兼容安卓的“纯血鸿蒙”--HarmonyOS NEXT鸿蒙星河版最终面世,并与2024年Q4正…...

C++17之std::invoke: 使用和原理探究(全)

C进阶专栏:http://t.csdnimg.cn/5mV9r 目录 1.概述 2.辅助类 3.原理分析 4.总结 1.概述 在之前的 C 版本中,要调用不同类型的可调用对象,需要使用不同的语法,例如使用函数调用运算符 () 来调用函数或函数指针,使用…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

【位运算】消失的两个数字(hard)

消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

ios苹果系统,js 滑动屏幕、锚定无效

现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

【Oracle】分区表

个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

深度学习习题2

1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...