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

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

相关文章

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

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

golang内存对齐的项目实践

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

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

使用Java实现获取客户端IP地址

《使用Java实现获取客户端IP地址》这篇文章主要为大家详细介绍了如何使用Java实现获取客户端IP地址,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 首先是获取 IP,直接上代码import org.springframework.web.context.request.Requ

Linux内存泄露的原因排查和解决方案(内存管理方法)

《Linux内存泄露的原因排查和解决方案(内存管理方法)》文章主要介绍了运维团队在Linux处理LB服务内存暴涨、内存报警问题的过程,从发现问题、排查原因到制定解决方案,并从中学习了Linux内存管理... 目录一、问题二、排查过程三、解决方案四、内存管理方法1)linux内存寻址2)Linux分页机制3)

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭