使用 UWA Gears 定位游戏内存问题

UWA Gears 是UWA最新发布的无SDK性能分析工具。针对移动平台,提供了实时监测和截帧分析功能,帮助您精准定位性能热点,提升应用的整体表现。

内存不足、内存泄漏和过度使用等问题,常常导致游戏出现卡顿、崩溃,甚至影响用户体验。本文将详细介绍Gears-Realtime模式中Memory Detail参数,并通过实例演示如何定位和解决游戏中的内存问题。

1. 深入分析内存细节:Memory Detail

要深入地理解内存问题,我们可以借助Memory Detail参数,查看应用内存的具体分布和使用情况。

总体内存使用情况

  • PSS Total
    PSS Total(Proportional Set Size)是衡量进程实际占用物理内存的重要指标,它通过按比例分配共享内存来计算应用的物理内存占用情况。PSS Total通常在应用加载大量资源或数据时增长,如启动新场景或关卡。如果PSS Total持续增长,可能意味着存在内存泄漏或资源未及时释放的问题,长此以往可能导致设备内存耗尽,进而导致应用崩溃。

  • Unknown
    Unknown内存表示未归类的内存使用,通常代表应用中没有明确分类的内存分配。当应用中某些资源或数据无法被现有分类系统识别时,Unknown内存可能会增长。持续的Unknown内存增长可能表明有资源未能及时释放,或某些内存分配没有被合理管理,这可能导致内存泄漏和资源浪费。

堆内存使用情况

  • Native Heap
    Native Heap是由C/C++代码分配的堆内存,主要用于存储应用中的原生对象和数据。Native Heap通常在应用使用复杂的C/C++算法或加载大型原生资源(如音频、视频文件)时增长。如果Native Heap占用持续增加,可能意味着存在内存泄漏,或者分配的内存未能及时释放,这将导致内存碎片化和应用性能的下降。

  • Dalvik Heap
    Dalvik Heap用于表示Dalvik虚拟机管理的Java对象的内存占用情况,是Java应用中内存使用的主要指标。Dalvik Heap会在创建大量Java对象或加载大量Java资源时增长,例如运行复杂逻辑或大量实例化对象时。如果Dalvik Heap增长过快,可能引发频繁的垃圾回收(GC),导致应用性能下降和用户体验不佳。

图形渲染内存使用情况

  • GL mtrack
    GL mtrack监控与OpenGL图形渲染相关的内存使用,包括纹理和渲染缓冲区的内存分配。在加载高分辨率纹理、大型3D模型或在高负载的渲染场景中,GL mtrack的内存占用会显著增长。如果增长过快且未及时释放,可能导致GPU内存不足,引发帧率下降、渲染延迟甚至应用崩溃。

  • EGL mtrack
    EGL mtrack与EGL(OpenGL ES的原生窗口系统接口)相关,监控EGL资源的内存使用。在应用中频繁创建和销毁EGL上下文时,EGL mtrack的内存占用会增长。如果这些资源未能及时释放,会导致内存浪费,并影响图形渲染的性能。

  • Gfx Dev
    Gfx Dev表示与图形设备相关的内存使用,通常用于管理GPU的渲染资源。在进行复杂的图形操作或处理大量图形数据时,Gfx Dev的内存占用会增加。如果增长过快,可能导致GPU资源紧张,进而影响渲染性能。

内存映射使用情况

  • SO mmap
    SO mmap用于表示共享库的内存映射,主要涉及.so文件的内存使用。在应用加载多个共享库或动态链接库时,SO mmap的内存占用会增长。如果共享库数量过多或未能及时卸载,可能导致内存占用增加,并影响应用的启动时间和运行性能。

  • JAR mmap
    JAR mmap表示JAR(Java ARchive)文件的内存映射,主要用于管理Java类库的内存分配。在应用加载大量Java类库或资源时,JAR mmap的内存占用会增加。如果未能合理管理和释放这些资源,可能导致内存占用不断增加,影响应用的性能和响应速度。

  • APK mmap
    APK mmap表示APK(Android应用程序包)文件的内存映射,主要涉及应用自身资源的内存使用。在加载应用的资源文件(如图片、音频、视频)时,APK mmap的内存占用会增加。如果这些资源未能高效管理,可能导致内存占用增加,影响应用的启动速度和运行效率。

  • DEX mmap
    DEX mmap表示DEX(Dalvik Executable)文件的内存映射,包含应用经过编译的字节码。在应用加载多个DEX文件或扩展包时,DEX mmap的内存占用会增加。如果这些字节码未能有效管理,可能导致内存占用增加,影响应用的性能和稳定性。

  • OAT mmap
    OAT mmap表示OAT(Optimized Android Runtime)文件的内存映射,包含优化后的应用程序代码。在应用运行时,加载优化的OAT文件会占用一定的内存。如果OAT文件过大或加载过程不够高效,可能导致内存占用增加,并影响应用的运行速度。

  • ART mmap
    ART mmap表示ART(Android Runtime)虚拟机的内存映射,主要涉及ART虚拟机运行时的内存使用。在ART虚拟机处理Java字节码和优化操作时,ART mmap的内存占用会增加。如果ART内存管理不当,可能导致内存占用增加,影响应用的执行效率。

  • Other mmap
    Other mmap表示其他类型的内存映射,未被归类到特定类型的内存使用。在应用加载非标准资源或使用特殊内存映射时,Other mmap的内存占用会增长。如果这些内存区域未能及时释放,可能导致内存占用增加,影响系统的整体性能。

其他内存使用情况

  • Dalvik Other
    Dalvik Other表示Dalvik虚拟机的其他内存使用,涵盖了非堆内存的部分。通常在Dalvik虚拟机执行非堆内存操作时,这一参数的内存占用会增长。如果虚拟机内存管理不当,可能导致内存浪费,并影响应用的响应速度。

  • Other Dev
    Other Dev表示与设备相关的其他内存使用,通常用于管理与设备特性相关的数据存储。在应用使用特殊硬件功能或与设备进行频繁交互时,Other Dev的内存占用可能增长。如果未能高效管理这些资源,可能导致设备性能下降或内存占用增加。

  • Stack
    Stack表示堆栈内存的使用情况,主要用于存储线程的堆栈信息。在创建新线程或执行复杂操作时,Stack的内存占用会增长。如果线程管理不当或堆栈内存使用过多,可能导致应用的响应速度下降,甚至引发崩溃。

  • Ashmem
    Ashmem(Anonymous Shared Memory)表示匿名共享内存的使用情况,主要用于跨进程共享内存数据。在应用需要在多个进程间共享数据时,Ashmem的内存占用会增加。如果共享内存未能及时释放或管理不当,可能导致内存浪费,并影响系统的稳定性。

通过分析这些细节数据,大家可以更准确地定位内存问题的根源,并采取相应的优化措施,如优化资源加载策略、及时释放不必要的对象等。

2. 实例分析

为帮助大家更好地通过Gears定位内存问题,我们来结合一个具体的游戏实例进行分析,并深入解读相关的性能参数。

背景信息
测试人员在游戏测试的过程中发现,游戏在特定的关卡游玩了10分钟后,出现了闪退现象,初步怀疑可能是因为内存问题导致。

首先,获取性能数据:
我们使用Realtime模式对该游戏进行一定时间的性能测试,获取部分性能数据,便于后续分析。

优化前的性能测试数据趋势图

优化前开始时的测试数据展示图

优化前结束时的测试数据展示图

接着,分析性能数据:
我们可以从上图中观察到,优化前的性能测试数据趋势线成阶梯形增长,而从具体数据来看:

  • PSS Total内存占用在应用运行过程中显著增加,最终达到1.27GB。这表明应用存在严重的内存累积问题,可能是由于内存泄漏或资源未及时释放导致的。

  • Unknown内存增长尤为显著,从135.32MB增长至577.89MB。Unknown内存通常代表未能被归类的内存分配,其大幅增长通常意味着应用中存在未被正确管理的资源或隐性的内存分配问题。这是内存管理的关键问题,可能导致系统内存紧张,从而影响应用的性能和稳定性。

  • GL mtrack内存从163.55MB显著增长至630.84MB,这表明在应用的图形资源管理方面存在严重问题。内存的快速增长可能是由于图形资源未能及时释放或频繁加载大规模图形资源所致。这种内存的急剧增加可能会导致GPU内存压力增大,从而影响渲染性能,最终可能导致帧率下降、画面卡顿,甚至应用崩溃。

结合以上的数据,我们可以发现主要问题集中在PSS Total和Unknown内存的显著增长,以及GL mtrack内存的急剧上升。这些问题表明应用存在严重的内存管理不足,尤其是在图形资源管理方面,可能导致内存泄漏、资源未能及时释放,以及GPU内存过度消耗。这些问题如果不及时优化,可能会导致系统内存不足、应用性能下降,甚至导致应用崩溃。

然后,优化性能问题:
在分析了存在内存问题的性能数据后,我们发现Unknown内存的大幅增长是主要的内存问题之一。Unknown内存并不是某种特殊的内存,而是指无法明确分类的内存部分。大部分的性能分析工具都无法直接识别和定位Unknown内存的具体来源,那么我们该如何去定位并解决Unknown内存问题呢?

主要可以从以下几点来优化:

  • 分析内存增长的时间点
    通过观察内存曲线,识别出内存问题开始的时间点,并回溯到该时段前后执行的代码段,初步判断可能导致内存问题的操作。

  • 关联代码与测试场景
    对照测试场景的步骤,列出在内存增长明显的时间点所执行的操作,并将其与相关代码段对应,初步锁定可疑代码区域。

  • 逐步禁用功能模块
    禁用初步锁定的可疑模块或功能特性,并重新运行测试,观察内存问题是否改善。通过这一过程,进一步缩小问题范围。

  • 细化代码调试
    在可疑代码段内逐行或逐函数分析内存分配操作,特别是涉及到动态内存分配、对象创建等部分,加入日志记录,跟踪内存操作的细节。

  • 内存快照对比
    在内存增长的关键时刻使用内存快照工具捕获内存状态,对比不同时间点的快照,识别出内存增长的具体对象或数据结构,以进一步锁定问题代码。

  • 使用二分法进一步定位
    通过二分法调试将可疑代码区域逐步划分为更小的部分,逐步排查,直到找出具体导致内存问题的代码段,并进行针对性修复。

  • 重复测试验证
    每次定位并修改代码后,重新运行测试场景,验证内存问题是否解决,逐步收窄问题范围,直到彻底消除内存问题。

最后,验证优化结果:

在对游戏进行优化后,我们需要重新进行性能测试来验证优化的结果。

优化后的性能测试数据图

通过查看优化后的数据趋势,我们可以发现优化措施显著改善了应用的内存管理,PSS Total和Unknown内存的稳定性验证了内存累积和泄漏问题得到了解决。同时,系统可用内存的增加进一步确保了应用在长时间运行后的性能和稳定性。

希望这篇文章能够帮助大家使用Gears-Realtime模式快速定位内存问题,在优化内存的道路上披荆斩棘。


如果您在使用过程中遇到任何问题,可以通过私信找到我们,或者前往问答社区进行提问,我们将竭诚为您提供支持。

问答社区链接:UWA问答 | 游戏开发者互动问答社区 | 侑虎科技

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/54595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS | 如何来避免 FOUC(无样式内容闪烁)现象的发生?

一、什么是 FOUC(无样式内容闪烁)? ‌FOUC(Flash of Unstyled Content)是指网页在加载过程中,由于CSS样式加载延迟或加载顺序不当,导致页面出现闪烁或呈现出未样式化的内容的现象。‌ 这种现象通常发生在HTML文档已经加载&…

Redis数据结构之哈希表

这里的哈希表说的是value的类型是哈希表 一.相关命令 1.hset key field value 一次可以设置多个 返回值是设置成功的个数 注意,哈希表中的键值对,键是唯一的而值可以重复 所以有下面的结果: key中原来已经有了f1,所以再使用hse…

RTSP学习

RTSP基本原理 实时流传输协议(RTSP:RealTimeStreaming Protocol1)是一种网络传输协议,旨在发送低延迟流。 该协议由RealNetworks,Netscape和哥伦比亚大学的专家在1996年开发。它定义了应如何打包流中的数据以进行传输。 类似一个控制命令的协议play teardown 负责音视频的数据…

二叉树(Java)

一.1.树形结构概念的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:…

大模型培训讲师叶梓:Llama Factory 微调模型实战分享提纲

LLaMA-Factory ——一个高效、易用的大模型训练与微调平台。它支持多种预训练模型,并且提供了丰富的训练算法,包括增量预训练、多模态指令监督微调、奖励模型训练等。 LLaMA-Factory的优势在于其简单易用的界面和强大的功能。用户可以在不编写任何代码的…

【速成Redis】03 Redis 五大高级数据结构介绍及其常用命令 | 消息队列、地理空间、HyperLogLog、BitMap、BitField

前言: 上篇博客我们讲到redis五大基本数据类型(也是就下图的第一列)。 【速成Redis】02 Redis 五大基本数据类型常用命令-CSDN博客文章浏览阅读1k次,点赞24次,收藏10次。该篇适用于速成redis。本篇我们将讲解&#…

Leetcode 2246. 相邻字符不同的最长路径(一般树)树形dp C++实现

问题:Leetcode 2246. 相邻字符不同的最长路径 给你一棵 树(即一个连通、无向、无环图),根节点是节点 0 ,这棵树由编号从 0 到 n - 1 的 n 个节点组成。用下标从 0 开始、长度为 n 的数组 parent 来表示这棵树&#x…

001.从0开始实现线性回归(pytorch)

000动手从0实现线性回归 0. 背景介绍 我们构造一个简单的人工训练数据集,它可以使我们能够直观比较学到的参数和真实的模型参数的区别。 设训练数据集样本数为1000,输入个数(特征数)为2。给定随机生成的批量样本特征 X∈R10002 …

【Delphi】扩展现有组件创建新的 FireMonkey 组件(步骤二)

实现指定格式的属性 步骤 1 中创建的 TClockLabel 组件需要在显示当前时间时定义日期时间格式作为属性,以便组件用户可以指定。 一、实现指定格式的属性 要实现格式属性,请在 TClockLabel class 的发布部分添加以下一行: property Form…

CST电磁仿真77GHz汽车雷达保险杠

77G毫米波雷达仿真时,要考虑天线罩和保险杠的影响。通常保险杠都是多层结构,有的层非常薄。如果采用传统的3D建模方法,会导致网格数量巨大,进而影响到求解效率。 三维保险杠(bumper)模型如下图所示&…

【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析

文章目录 C string 类详解:从入门到精通前言第一章:C 语言中的字符串 vs C string 类1.1 C 语言中的字符串1.2 C string 类的优势 第二章:string 类的构造与基础操作2.1 string 类的构造方法2.1.1 示例代码:构造字符串 2.2 string…

部署自己的对话大模型,使用Ollama + Qwen2 +FastGPT 实现

部署资源 AUTODL 使用最小3080Ti 资源,cuda > 12.0使用云服务器,部署fastGPT oneAPI,M3E 模型 操作步骤 配置代理 export HF_ENDPOINThttps://hf-mirror.com下载qwen2模型 - 如何下载huggingface huggingface-cli download Qwen/Qwen2-…

flutter遇到问题及解决方案

目录 1、easy_refresh相关问题 2、 父子作用域关联问题 3. 刘海屏底部安全距离 4. 了解保证金弹窗 iOS端闪退 (待优化) 5. loading无法消失 6. dialog蒙版问题 7. 倒计时优化 8. scrollController.offset报错 9. 断点不走 10.我的出价报红 11…

Python3爬虫教程-HTTP基本原理

HTTP基本原理 1,URL组成部分详解2,HTTP和HTTPS3,HTTP请求过程4,请求(Request)请求方法(Request Method)请求的网址(Request URL)请求头(Request H…

Redmi Note 7 Pro(violet)免授权9008文件分享及刷机教程

获取文件 关注微信公众号 heStudio Community回复 violet_9008 获取下载链接。 刷机教程 下载搞机助手(可以从上方文件中获取)并安装。手机按音量减键和电源键进入 Fastboot 模式, 打开搞机助手,点击进入 9008 模式 等待手机…

IDEA 关闭自动补全功能(最新版本)

文章目录 一、前言二、关闭自动补全三、最终效果 一、前言 在最新的 IDEA 中发布了自动补全功能,当你输入代码时,IDEA 会自动显示你可能想输入的代码,减少手动输入的工作量,它会根据上下文提供正确的选项,提高代码的准…

Java-数据结构-二叉树-习题(三)  ̄へ ̄

文本目录: ❄️一、习题一(前序遍历非递归): ▶ 思路: ▶ 代码: ❄️二、习题二(中序遍历非递归): ▶ 思路: ▶ 代码: ❄️三、习题三(后序遍历非递归): ▶ 思路: …

vue使用PDF.JS踩的坑--部署到服务器上显示pdf.mjs viewer.mjs找不到资源

之前项目使用的pdf.js 是2.15.349版本,最近换了一个4.6.82的版本,在本地上浏览文件运行的好好的,但是发布到服务器(IIS)上打不开文件,控制台提示找不到pdf.mjs viewer.mjs。 之前使用的2.15.349pdf和viewer…

Git使用手册

1、初识Git 概述:Git 是一个开源的分布式版本控制系统,可以有效、高速地处理项目版本管理。 知识点补充: 版本控制:一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 分布式:每个人…