游戏客户端性能(内存)【前篇】

2024-03-25 23:08

本文主要是介绍游戏客户端性能(内存)【前篇】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文由5t5发表于TesterHome社区,原文链接

内存问题——落叶归根🔰

内存,大家最熟悉不过的一块内容,也可能最不了解的一块内容,熟悉是因为听到这个词的频率非常高,【啊,我内存不够了,手机好卡啊】这是我听到过最多的吐槽,不熟悉是,内存怎么工作,内存的数据交换过程中都谁参与了,内存对于设备来说,如果出现极端场景的话,设备会有什么影响?等等…等等…一堆的问题都好像跟内存相关,今天就按照测试向去理解探讨下内存在客户端性能中的一面。

展示方式

1、内存的科学解释(摘百度)哈哈;
2、内存在性能测试中的表现形式;
3、内存的类型以及含义;
4、内存的特殊表现有哪些?
5、内存数据在版本迭代过程中扮演的角色以及重要性;

科学解释

内存 (Memory) 是计算机的重要部件之一,也称内存储器和主存储器,它用于暂时存放 CPU 中的运算数据,与硬盘等外部存储器交换的数据。它是外存与 CPU 进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平。只要计算机开始运行,操作系统就会把需要运算的数据从内存调到 CPU 中进行运算,当运算完成,CPU 将结果传送出来。

内存在性能中的表现

内存泄漏【重点关注】
首当其冲,内存泄漏问题可谓是听的最多,导致移动端崩溃闪退的情况最多的元凶之一,内存泄漏问题上,初步接触性能测试的人员一直存在一个误区,那就是在测试过程中,内存一直处于上升状态是不是就是发生了内存泄漏问题?答案是否定的,我们先来看看游戏客户端性能的过程中发生内存泄漏时,如何正确判断发生了泄漏。

解释下正常泄漏时的原因
图中可以看出在特定的某个场景,内存申请是相对固定的情况,却每次使用该场景时引用的资源脚本,有固定的几个内存对象遗漏,随着使用该场景次数的增加,内存的值会有轻微/严重的增长,并且不会被清除,这部分内存就是泄漏造成的。图中的 5MB 就是泄漏的内存。

泄漏时测试的执行手段以及常用场景
举个栗子,副本泄漏测试,可以发现每次从副本返回之后内存的基准值在不断的上升,这就意味着副本中有资源/代码堆未卸载干净,有泄漏,这样的话,副本的泄漏测试问题就定位出来,而具体的内存泄漏是什么?见下一章

延伸:副本泄漏测试如此,举一反三,其他的泄漏问题同样适用,如:UI 泄漏测试,频繁打开关闭 UI 跳转界面,查看表现,跑马灯测试,频繁的唤起跑马灯内容,查看内存变化,都是可以的。

内存基数高

内存基数过高就很简单了,是针对于内存分配极度不合理的情概况去看的。
举个栗子,查看下图,我们发现在登录界面时,内存就已经飙升到 500MB,而进入核心的场景后才 650MB,严重说明,登录阶段存在严重的内存分配不合理的情况。需要优化,后续需要针对性的把资源占用较大的内容优化或者删除。

内存峰值

内存峰值也相对简单,但是又属于比较重要的部分,因为它是评估项目在设备上是否存在崩溃风险的一个指标。
举个栗子,我们来看一下,每个项目我们在跑完核心流程的过程中,内存值都会存在一个最大值,这个值就是内存峰值,内存峰值的出现意味着项目可能达到的一个极限值,上回我们也说到,硬件决定项目的上限,如果内存过高超过上限,设备就会干掉项目,峰值的意义就是如此。

延伸:比如 iOS 设备就是 1G 运存机型,645~649MB 就会杀掉进程,2G 运存机型,1400MB 就会杀掉进程。Android 设备也存在类似的现象,但是现在机型都解禁,底层内存不足会优先杀掉未使用队列进程,涉及底层调度问题后续介绍。

内存冗余

顾名思义,就是这部分的内存是多余的,而且它大多会响应在开发中最常用的池应用,以及需求变动的过程中。内存冗余就相对复杂一些,理解会好理解,定位会麻烦且复杂一些,具体定位方式放后篇。

内存类型以及含义

VSS : Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS : Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS : Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS : Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)

常用的就只有 VSS 与 PSS 两个,虚拟内存在测试过程中用来判断申请内存时的一个内存状态,PSS 则是真实运行项目时,真实所占用的项目资源 + 项目代码堆 + 三方库/系统库引用时占用部分的内存是最真实反应。前者因为虚拟基址 Google 官方有限制为 0~4G 避免出现杀进程的情况,后者则就是我们最常看的内存值。

介绍 PSS 内存中不同类型
我们知道 Perfdog 中 memory detail 栏内存类型取自 adb meminfo 的内存类型,但是取值上会有些差别,后期感兴趣的可以给各位留个作业,看一下,内存类型不同在哪里?取值有差异时是什么原因?

Perfdog memory detail 如下图展示

adb dumpsys meminfo {}获取指标如下展示

上图中我们发现,meminfo 的内存类型很多,Perfdog 取内存类型时,并没有全部都取,而是取到了一部分,而这部分基本就够用了,也跟 TX 本身游戏项目多用于 Unity 引擎有一定的关系。因此我们只需要理解其中一部分大头内存类型即可,足以快速定位到很多内存问题。
特殊提醒:感兴趣的可以延伸的去里了解 meminfo 中的内存类型都是什么意思,这个不多赘述了。

从上图中可以看出内存的类型常用并且要观察的就是:
NativePss:项目中常驻内存,包含的就是常用资源文件,库文件,以及脚本文件;
Gfx/GL:反映的基本上就是渲染底层驱动给到的内存,我这里一般就认为是"显存",他们具体的区别这里我也没有深究,只知道不同的设备取值时,时而是 Gfx,时而是 GL,因此我猜测都是显存理解,如果有出入,欢迎交流;
unknow:在 Unity 项目中一般就理解为 Mono 堆,其他项目未延伸去理解,感兴趣的依然可以去拓展延伸的了解。

内存的特殊表现【不分先后】

内存压缩
内存值中存在内存交换区域,名为 swap,用来压缩缓存,保留不常用/通用内存,它属于底层调度的一部分,也是真实反应在 PSS 内存中的,因此真实的内存计算规则是:内存 memory+ 交换内存 swap memory,如果一旦 swap memory 升高意味着有部分内存在后台做压缩处理,而压缩的操作是由 CPU 来参与的,无疑加重了 CPU 的开销,中低端机上就会表现出机身发热,卡顿的情况,后篇着重介绍。

显存升高
显存升高直接反应的情况也是底层硬件调度机制有关,我们目前只需要知道显存是用来保留渲染数据产生的内存做缓冲去做预留,如果它升高意味着在传输 I/O 阶段存在瓶颈,需要优化渲染流程,后篇会着重解释。

内存值的扮演角色以及迭代时应用
扮演角色
主角,妥妥的主角,它的影响关乎项目的生死,也是项目中重点关注的指标之一,上述的内存情况都要一一考虑去评估,反应在每次版本迭代中。
迭代应用
同上篇的流畅度一致,可以在迭代过程中作为评估优化效果,竞品分析等的一项衡量指标去做记录。

总结

综上所述
1、内存分多种类型,主要关注 PSS;
2、内存在不同表现下,场景不同,评估方式也不同;
3、内存在客户端性能中地位很高,也是重点关注的对象,需要认真去看,着重去分析;
4、内存涉及部分 I/O 阻塞,其他硬件方便的内容;

image
以上是今天的分享,你学废了吗~
想学习更多干货知识和前沿技术?
想结识测试行业大咖和业界精英?
欢迎关注 「第十届MTSC测试开发大会」

这篇关于游戏客户端性能(内存)【前篇】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/846544

相关文章

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Golang中拼接字符串的6种方式性能对比

《Golang中拼接字符串的6种方式性能对比》golang的string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去,主要有6种拼接方式,下面小编就来为大家详细讲讲吧... 目录拼接方式介绍性能对比测试代码测试结果源码分析golang的string类型是不可修改的,对于拼接字

Redis客户端工具之RedisInsight的下载方式

《Redis客户端工具之RedisInsight的下载方式》RedisInsight是Redis官方提供的图形化客户端工具,下载步骤包括访问Redis官网、选择RedisInsight、下载链接、注册... 目录Redis客户端工具RedisInsight的下载一、点击进入Redis官网二、点击RedisI

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Golang基于内存的键值存储缓存库go-cache

《Golang基于内存的键值存储缓存库go-cache》go-cache是一个内存中的key:valuestore/cache库,适用于单机应用程序,本文主要介绍了Golang基于内存的键值存储缓存库... 目录文档安装方法示例1示例2使用注意点优点缺点go-cache 和 Redis 缓存对比1)功能特性

mysql线上查询之前要性能调优的技巧及示例

《mysql线上查询之前要性能调优的技巧及示例》文章介绍了查询优化的几种方法,包括使用索引、避免不必要的列和行、有效的JOIN策略、子查询和派生表的优化、查询提示和优化器提示等,这些方法可以帮助提高数... 目录避免不必要的列和行使用有效的JOIN策略使用子查询和派生表时要小心使用查询提示和优化器提示其他常

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内