Unity内存分析与优化实践

news2024/12/22 23:06:42

目录

  • 前言
  • 优化前分析
    • Committed Memory Tracking Status
    • Memory Usage
  • 开始内存优化
    • 贴图优化
      • 贴图分辨率优化
      • 去除透明通道和mipmap
      • 其他关于贴图的优化技术
    • Shader优化
      • 优化Always Included Shaders
      • 优化Preloaded Shaders
      • 优化Shader代码
      • 共享Shader
    • 优化Mesh
    • 降低屏幕分辨率
    • 优化效果内存占用
    • 其他内存优化
  • 优化结果总结

前言

在移动端项目中,内存占用是一项非常重要的指标,一般都会被严格控制其大小,否则会导致内存占用过大而影响其他功能的使用。而在移动端Unity中,由于嵌入了Unity引擎,内存占用会一下子飙升,如果控制不好内存的增长,恐怕许多项目都不会允许Unity嵌入到移动端中,在这种时候,内存优化就变得尤为重要,接下来我就在实践中一步一步地对移动端Unity项目进行内存优化,通过工具分析和多角度优化内存,让大家可以清晰地看到内存优化的效果和掌握优化手段。

优化前分析

为了得到清晰的优化情况对比,我们先把优化前的App内存占用情况记录一下。一般情况下,查看Unity的内存占用可以使用Unity的Profile工具,但是该工具对内存占用的情况显示不是很详细,所以这里我们使用Memory Profile进行内存分析,Memory Profile的安装使用可以查看这个链接:Memory Profile官方文档,我们打开App,然后使用Memory Profile去抓一下快照,可以看到快照信息如下:
在这里插入图片描述

我们这里可以对整体的内存进行分析,这里大概说下每个各个部分的含义,便于我们理解内存占用构成:

Committed Memory Tracking Status

这个是设备提交的内存情况,可以用来看正在使用内存是多少,预留了多少内存

  • Total(总内存):表示Unity进程当前使用的总内存量。这包括所有已分配给Unity的内存,无论是实际使用中的内存还是预留的内存

  • In Use Memory(使用中内存):表示当前实际使用中的内存量。它反映了Unity正在使用的资源占用的内存大小,涵盖了纹理、模型、声音等加载的资源。

  • Reserved Memory(已预留内存):表示Unity为未来使用而预留的内存量。这些内存可能由于资源加载和运行时需求而保留,但尚未实际使用。

Memory Usage

在这里可以看到程序各部分占用的内存,可以方便我们针对性分析和解决内存占用问题

  • Managed Heap:是指运行在托管环境中,由.NET运行时(例如Unity使用的Mono或IL2CPP)管理的内存堆

  • Virtual Machine(IL2CPP):与IL2CPP虚拟机相关的内存占用

  • Graphics & Graphics Driver:图形渲染和图形驱动程序内存占用,一般和画面复杂度,分辨率,纹理,各种缓冲区,各种渲染技术特效等等相关

  • Audio:音频部分,和音频文件数据占用内存相关

  • Other Native Memory:这部分内存用于存储临时数据、中间计算结果、状态信息等

  • Profiler:用于分析性能的,这个一般无需理会,正式版本没这个

  • Executabe & DLLs:可执行文件和动态链接库的内存占用

从上面这些可以看到总览的内存占比,便于我们对整个程序的内存占用情况有比较全面的了解,接下来我们再看看更详细的内存占用情况,我们点击Tree Map菜单,可以看到Memory Usage Overview界面,下面列举了各个部分占用的情况:

在这里插入图片描述

从这些部分中就可以找出需要优化的点,我们点击较大的方块,比如Texture2d,就能看到下面详细的内存占用情况:

在这里插入图片描述

从图中可以看到,第一项占用21.3 MB,其他的占用会小一点,但是在移动端这些都是可以优化的点。第一项我们无法看出命名是什么,其实这里是中文命名的乱码,因此最好不要使用中文命名,否则不知道具体是什么导致的内存占用。我们点击第一项,可以看到以下界面:

请添加图片描述

可以从这里看到引用的物体,但是由于中文问题,导致依然不知道是哪个贴图,所以大家一定不要用中文的命名。这里每一部分都点进去看看,就能看到各项的内存占用,具体每部分的情况我就不贴出来了,接下来我们开始优化内存。

开始内存优化

贴图优化

贴图分辨率优化

一般贴图的内存占用是占Unity的内存大头的,因此我们首先需要对贴图进行优化,我们首先降低贴图的分辨率,这里为了快速就统一设置贴图最大分辨率为512了,实际工程中最好是为每个贴图设置最佳分辨率,设置最大分辨率的地方在:
在这里插入图片描述

我们看看优化效果:

在这里插入图片描述

可以看到,texture2d从74.7M降低到35.4MB,如果场景中高分辨率贴图多,那么这个优化将会更大。

去除透明通道和mipmap

一些贴图是不需要带上透明通道的,可以去除减小内存大小。还有就是mipmap,开启mipmap会增大大概1/3的内存大小。如果项目中没有远近景的切换,是用不到mipmap的,也可以关掉:

在这里插入图片描述

需要注意的是,这两项是否可以关闭需要根据项目实际情况而定,而且其实优化不是很大,以下是在测试项目中优化的效果(测试项目的贴图较少,优化程度很低):
在这里插入图片描述

只是从35.4M变成了34.1M而已,优化掉了1.3M。

其他关于贴图的优化技术

除了上述这两个操作外,还有一些其他的贴图优化技术,可以根据项目情况使用,比如利用Photoshop之类的工具对贴图进行专门的优化,保持效果的同时优化内存占用。也可以使用纹理合并,把多个小纹理合并为一个大的纹理图集,减少纹理的切换和内存开销。这些就看实际项目去做具体优化了。

Shader优化

shader的内存占用一般和shader的编写和加载有关,通常情况下不会占用特别大,除非shader编写特别复杂,变体特别多,这里就不详细每个步骤都讲述内存变化了,在执行多个操作后再统一看内存变化。

优化Always Included Shaders

Always Included Shaders在Unity设置的Graphics下面,是用于包含那些暂时没有引用但是在需要时动态加载的shader的,但是在这里的shader会无论用不用得到都会加载进去,不仅会增大内存,还会增加编译时间,所以尽量不要放在这里

优化Preloaded Shaders

"Always Included Shaders"和"Preload Shaders"是两种不同的Shader预加载选项,"Always Included Shaders"是一种将Shader直接包含在构建输出中的选项。这意味着不管场景中是否使用了这些Shader,它们都会被打包到构建中。而"Preload Shaders"是一种在运行时提前加载Shader的选项。这意味着只有在需要使用这些Shader时才会进行加载。这里需要填入的是一个shader变体集合,也要记得避免把集合中用不到的shader和其变体去掉,避免内存占用

优化Shader代码

在移动端尽量不要使用过于复杂的shader,可以尽量减少shader的pass,同时不要生成过多的变体,尽量做到简单高效。

共享Shader

如果多个如果多个对象使用相同的材质和Shader,可以考虑将它们合并为一个大的网格,以减少重复的Shader实例。这样可以节省内存并提高性能。

本次测试项目中使用到的shader不多也不复杂,通过上面这些技术,最终优化效果如下:

在这里插入图片描述

从一开始的38.1M降到37.2M,并且shader的数量也从54个降低到42个。

优化Mesh

  • 减少模型的面数可以显著降低内存占用

  • 将多个小模型合并为一个大的网格模型

  • 使用LOD(层次细节):根据物体与相机的距离,使用不同细节级别的模型,利用LOD功能可以降低模型的面数和纹理分辨率,以降低内存占用

  • 使用GPU Instancing:对于需要大量重复实例的模型,使用GPU Instancing技术可以共享材质和缓冲区数据,以减少内存开销。

  • 尽量避免使用骨骼动画:骨骼动画(Skinned Mesh Animation)通常消耗比较多的内存。如果没有必要,尽量使用其他动画技术(如顶点动画、物理动画),或者尝试使用成批处理(Batching)等技术来减少动画对象的数量。

  • 使用顶点压缩:Unity提供了顶点压缩选项,可以减小存储每个顶点所需的内存。您可以在导入模型时选择适当的压缩选项,例如使用Half精度来减小顶点的内存消耗

对于模型Mesh部分,优化大头在于模型的制作简化这里,尽量使用低模,模型细节用别的技术模拟实现,而不要增加过多面数,测试项目中用到的模型已经是最简,这里就基本没什么优化空间了。

降低屏幕分辨率

降低屏幕分辨率也可以减少整体的内存占用,例如从19201080降低到1280720,可以看到效果:

在这里插入图片描述

可以看到,RenderTexture大幅度降低,优化幅度非常大,因此在移动端,分辨率这一项设置变得非常重要,尽量使用较低分辨率。

优化效果内存占用

一般项目中还会用到一些类似于后处理,抗锯齿,阴影,灯光数量等方面的效果,虽然视觉上确实会增加不少,但是内存也跟着增加上来了,所以尽量也要减少这些方面的使用。在测试项目中,后处理使用到了

  • Post Process全局后处理

  • TTA抗锯齿

  • Bloom

  • 高质量阴影

  • lighting count为6

针对上面这些进行优化:

  • 去掉Post Process全局后处理

  • TTA抗锯齿换成Unity自带的MSAA抗锯齿,设置为2x

  • Bloom使用Shader实现

  • 降低阴影质量

  • lighting count降低为4

最终得到的画面效果其实差别不会特别大,最终内存优化如下:

在这里插入图片描述

可以看到,各项占用内存再次大幅度降低,特别是RenderTexture,从29.7M降到了9.7M。

其他内存优化

一般情况下,内存占用最大的都是资源和效果,但还有一些其他的方面需要注意的,虽然本次测试项目中这些方面占比不大,但是也在这里列出来,在项目中也要注意这些方面的优化:

  • 动画的优化:一般项目使用动画都会使用动画控制器进行播放,但如果动画控制器里设置了较多的动画,则会占用不少内存。如果可以,使用动态加载动画的方式,用不到的动画及时卸载,避免内存占用。除此之外,动画数据的也不要太过于复杂,记得去除重复帧,减少关键帧,减少动画节点,这样会使动画变得更小,占用内存也会更小

  • 音频优化:音频部分也会占用不少的内存,可以强制使用单声道,压缩音频,重采样等方式减少内存占用

  • 代码优化:代码逻辑中也要注意内存的占用,不要滥用单例和静态类静态属性等。

优化结果总结

通过查看各个步骤的Memory Profile的Objects and Allocations的Total Size数据,可以得到较为准确的内存占用数据,最后得出的数据如下:

未优化贴图优化后Shader优化后降低屏幕分辨率后效果内存优化后
230.0M189.4M188.5M123.2M77.8M

可以看到,即使是一个比较简单的项目,经过一系列的内存优化后,也能达到一个非常不错的效果,但无论如何,在内存优化的过程中也不能一味的放弃质量,因此在项目里实际优化需要因情况而定,选择最适合项目的方式,尽量保持一个性能和效果都相对比较不错的情况。

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

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

相关文章

IDEA+Spring Boot+MyBatis+shiro+Layui+Mysql智能平台管理系统

IDEAJavaSpring BootMyBatisshiroLayuiMysql智能平台管理系统 一、系统介绍1.环境配置 二、系统展示1.登录2.注册3.发帖4.留言5.提交问卷6.展示公告7.查看文章8.管理员登录9.管理员管理10.用户管理11.问卷管理12.问卷结果管理13.帖子分类管理14.数据分析统计15.公告管理16.帖子…

基于线性准则的考虑风力发电不确定性的分布鲁棒优化机组组合(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Node.js知识梳理(二)——进阶

以下内容来自对《从前端到全栈》一书的学习记录~ 学习的时候用的是V16.20.0,18之后的语法差别还是有的~ 请求优化 我们在请求资源的时候,是需要做优化的,这里的优化涉及到了缓存。浏览器的缓存策略有两种: 强缓存协商缓存 关于…

分解整体:将整体式架构转换为微服务的容器化之旅

传统上,软件应用程序是使用单体架构开发的,其中所有应用程序组件都紧密交织在一起,并作为一个单元进行部署。随着软件应用变得更为复杂,组织开始依赖分布式系统,单体架构的限制开始变得更加明显。容器化被引入作为解决…

关于连接数据库时只能使用localhost而不能使用IP连接的问题解决办法

出现:java.sql.SQLException: null, message from server: "Host DESKTOP-H84MBU3 is not allowed to connect to this MySQL server"问题 解决办法: 1、打开数据库操作命令窗口 2、修改user表中 "root" 所对应的 "host&q…

JMeter之IP欺骗技术(模拟不同的IP地址并发请求)

目录 前言: 第一步:在负载机上绑定IP地址 第二步:点击高级,添加伪造的IP地址 第三步:新增IP地址复制到文本 第四步:新建参数化请求 第五步:新建压力测试脚本 第六步:配置线程…

【Mysql】事务原理与优化最佳实践(四)

前言 我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增 删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。 这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题&…

【C】函数

目录 【1】函数是什么 【2】C语言中函数的分类 【2.1】库函数 【2.2】如何学会使用库函数 【2.3】自定义函数 【3】函数的参数 【3.1】实际参数(实参) 【3.2】形式参数(形参) 【4】函数的调用 【4.1】传值调用 【4.2】传址调用 【…

kubernetes环境搭建及部署

一、kubernetes 概述 1、kubernetes 基本介绍 kubernetes,简称 K8s,是用 8 代替 8 个字符“ubernete”而成的缩写。是一个开源 的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化的 应用简单并且高效…

【Python】文件

文章目录 一. 什么是文件二. 文件路径三. 打开文件四. 关闭文件五. 写文件1. 清空写2. 追加写 六. 读文件1. 使用 read 方法读取2. 使用 for 循环按行读取3. 使用 readlines 方法读取整个文件的内容 七. 上下文管理器1. 什么是上下文管理器?2. 为什么要有上下文管理…

ESP8266模块MQTT AT Commands 发送 json字符串

ESP8266 wifi模块介绍 ESP8266EX 由乐鑫公司开发,提供了⼀套⾼度集成的 Wi-Fi SoC 解决⽅案,其低功耗、紧凑设计和⾼稳定性可以满⾜⽤户的需求。ESP8266EX 拥有完整的且⾃成体系的 Wi-Fi ⽹络功能,既能够独⽴应⽤,也可以作为从机…

ORA-31664: unable to construct unique job name when defaulted

某个环境备份不足空间问题处理后,手动执行expdp备份的脚本,报错如下 Export: Release 11.2.0.4.0 - Production on Tue Jul 4 11:46:14 2023 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle D…

【海量数据挖掘/数据分析】之 决策树模型(决策树模型、决策树构成、决策树常用算法、决策树性能要求、信息增益、信息增益计算公式、决策树信息增益计算实例)

【海量数据挖掘/数据分析】之 决策树模型(决策树模型、决策树构成、决策树常用算法、决策树性能要求、信息增益、信息增益计算公式、决策树信息增益计算实例) 目录 【海量数据挖掘/数据分析】之 决策树模型(决策树模型、决策树构成、决策树常…

Windows环境部署MySQL_5.7的安装、测试连接以及卸载全过程实操手册

前言: 前面记录了双环境的oracle的安装卸载及相关测试评估,这里记录下 MySQL5.7社区免费版的部署手册。 什么是 MySQL MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于Oracle 公司。MySQL 是一种关系型数…

window.open()实现PDF预览

效果图如下: 页面使用: window.open(strUrl) 参数说明如下图:

深度学习笔记之Transformer(四)铺垫:LayerNormalization

深度学习笔记之Transformer——LayerNormalization 引言回顾:批标准化问题描述问题处理 层标准化批标准化无法处理的问题 引言 在介绍 Transformer \text{Transformer} Transformer模型架构之前,首先介绍 Transformer \text{Transformer} Transformer的…

linux 环境下ElasticSearch 7.1.6.3、kibana-7.16.3安装

安装包放入百度网盘,自取 链接:https://pan.baidu.com/s/1Uh9pKFoaz9qi4CE4_GmlOA?pwdroky 提取码:roky 快速演示下安装操作: ElasticSearch 7.1.6.3: 1.上传至服务器相应目录下 我传到的/home目录下&#xff0…

0、技术选型

技术选型参考: 系统数据流程图 框架发行版本选型 1)如何选择Apache/CDH/HDP版本? (1)Apache:运维麻烦,组件间兼容性需要自己调研。(一般大厂使用,技术实力雄厚&#xf…

【随笔】jupyter notebook启动打开文件出现:500 : Internal Server Error

错误: 看log有 module ‘mistune’ has no attribute BlockGrammar’错误 打开文件有500 : Internal Server Error 解决方法: pip install --upgrade jupyterhub pip install --upgrade --user nbconvertconda环境可以: conda install nbc…

使用Python开发ChatGPT AI工具助手(ChatCatsy):4天快速开发指南

引言: ChatGPT是一种基于人工智能的对话生成模型,它可以用于开发聊天机器人、虚拟助手等应用。本教程将指导您在3天内使用Python开发一个ChatGPT AI工具助手。无需担心,即使您是初学者,也可以轻松跟随本指南完成项目。 第一天&a…