Unity UI内存泄漏优化

项目一运行,占用的内存越来越多,不会释放,导致GC越来越频繁,越来越慢,这些都是为什么呢,今天从UI方面谈起。

首先让我们来聊聊什么是内存泄漏呢?

一般来讲内存泄漏就是指我们的应用向内存申请了一块地址,然后这块地址的相关引用全部丢失了,这块内存无法再被分配,在计算机眼里,那就是丢了,找不回来了,除非重启。。。

不过,这里如果我们要去理解Unity中的内存泄漏,那我们首先要了解一下Unity的内存分配机制和GC机制,哇,不过说真的,要真是细说这两点,那真是几天都讲不完呀,还是算了,哈哈,这里大概聊一下,

程序在运行的时候,会先从计算机中申请一块内存,这时候如果我们需要去申请一块地址的时候,Unity会先去从堆内存中找合适大小的地址块给我们,但是这时候,如果堆内存用完了,这时候GC就出马了,会先清理一遍当前内存中无用的数据然后给我们分配所需要的内存块,那这个时候如果GC之后还是没有找到足够大小的内存给我们用怎么办呢,Unity只能去在申请一块之前内存2被大小的内存了。

这时候来想想,如果在我们的项目中这如果不断重复上述步骤,那么这时候是不是就意味着内存泄漏了呢。。。  现在就让我们开始从实际情况来一探究竟吧!!!

一开始我们通过Unity的Profiler工具只能看到在我们的UI已经关闭销毁了可是UI里面用到的图集还在内存里面存在,不应该呀,如果图集不释放,那岂不是意味着我们如果打开很多UI的时候,这些图集资源就要占到很多内存,如何查看当前内存中图集情况,可以参考下图,先选中Memory模块,然后选择Detailed,点击Take Sample Playmode,这时候内存中的图集就出现在下面了,参考5的位置,这里说明一下位置4这个选项,如果不勾选,进行内存采样速度会快很多,勾选了会慢很多,但是会同时采样出对应资源当前的引用情况。

这时候我们通过对游戏中不同节点进行内存采样,便能分析出我们哪些图集没有随着预设的销毁而销毁。

问题已经找到了,那么如何解决呢,如何下手呢,这时候又不知道怎么办了,害!!!

 但是生活还要继续,问题还得解决呀,那么接下来就开始了问题分析,无数次Demo测试,从AB包加载卸载,到Unity内存分配管理,从GC的工作方式,到GC的底层实现原理,终于发现了这几个问题。

首先,如果我们的项目是通过AssetBundle方式加载的,那么在我们切场景或者进行阶段变化的时候我们需要处理一下无用资源的释放,调用一下下面的接口。

Resources.UnloadUnusedAssets();

 卸载未使用的资源

 这时候我们在进行内存对比分析的时候会发现会有一些内存被释放,可是图集不销毁的问题还在,害,还以为挺简单的,目前看来问题更复杂了。。。

这时候用上了另一个工具Memory Profiler,这个工具是在Unity2020之后的版本推出的功能,对当前内存进行快照,可视化的形式显示当前内存分配的大小,列出了每个托管对象的类型,值,占用大小,地址,被引用链等等信息,还可以进行快照对比,分析两次内存快照新增、删除和保持不变的内存对象,从而更方便快捷的定位项目内存的使用情况。

通过对内存进行快照,分析图集的引用链,屏蔽代码,重新快照测试,一次次的测试,慢慢缩小代码范围,定位图集不销毁的原因,最终发现原来是我们的UI使用了static实例来实现单例效果,在其他地方调用,但是在我们UI不需要的时候并没有将这个静态单例设置为null,导致整个UI资源的相关引用一直存在,无法释放,还有就是我们在对按钮进行事件注册的时候,使用了项目封装的接口,而项目封装的接口在拿到委托事件对象后,并没有在移除事件的时候去清除委托事件对象,导致引用一直存在,相关的资源也就无法释放。

相信经过上述步骤之后我们的图集不销毁问题已经解决了大部分了,具体还有哪些,后面有需要我们再补充,哈哈。

这里再说一个图片不销毁问题,在项目中我们经常会去动态替换某些图片来实现我们的功能,这时候有一个统一接口就很方便了,可是图片不销毁问题也正好跟这个动态替换接口有关,由于我们的统一接口会保存一份加载的图片的引用,在对应预设销毁的时候,由于图片引用一直存在,所以图片就无法被GC处理掉,这时候我们可以考虑对我们动态加载的图片进行场景管理,在合适的时候清空一次引用列表,还有由于我们动态图片加载是自己管理加载资源,所以我们在清空列表的时候要调用一次对应接口的卸载资源接口,否则,资源还是无法从内存中释放。

目前为止,图集图片不销毁问题已经解决了大部分,至于项目中具体还有没有其他问题导致,有待后续研究,,,总结一下:

  • 使用了static静态类方式来实现单例的UI,在使用完之后一定记得将对应单例设置为null,让GC可以去释放对应的内存。
  • 在使用委托或者其他时候,拿到类对象的引用在使用完之后一定要记得释放引用。
  • 加载的资源在不适用的时候记得卸载掉,比如AssetBundle.Load()和AssetBundle.Unload()
  • 在适当的时机调用Resource.UnloadUnusedAssets()接口释放无用的资源

简而言之,言而简之,内存优化一直是项目开发中的重头戏,任重而道远呀。。。

 心怀梦想    奔向远方 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Lnton羚通关于PyTorch的保存和加载模型基础知识

SAVE AND LOAD THE MODEL (保存和加载模型) PyTorch 模型存储学习到的参数在内部状态字典中,称为 state_dict, 他们的持久化通过 torch.save 方法。 model models.shufflenet_v2_x0_5(pretrainedTrue) torch.save(model, "../../data/ShuffleNetV2_X0.5.pth…

【C++】AVL树(平衡二叉树)

目录 一、AVL树的定义二、AVL树的作用三、AVL树的插入操作插入——平衡因子的更新插入——左单旋插入——右单旋插入——左右双旋插入——右左双旋 四、ALVL树的验证五、AVL树的性能 一、AVL树的定义 AVL树,全称 平衡二叉搜索(排序)树。 二…

使用SpringBoot + Thymeleaf 完成简单的用户登录

😀前言 本篇博文是关于Thymeleaf 的综合案例, 使用SpringBoot Thymeleaf 完成简单的用户登录-列表功能,希望你能够喜欢😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨…

​Kubernetes的演变:从etcd到分布式SQL的过渡

DevRel领域专家Denis Magda表示,他偶然发现了一篇解释如何用PostgreSQL无缝替换etcd的文章。该文章指出,Kine项目作为外部etcd端点,可以将Kubernetes etcd请求转换为底层关系数据库的SQL查询。 受到这种方法的启发,Magda决定进一步…

Cat(5):API介绍—Event

Event 用来记录一件事发生的次数,比如记录系统异常,它和transaction相比缺少了时间的统计,开销比transaction要小。 Cat.logEvent 记录一个事件。 Cat.logEvent("URL.Server", "serverIp", Event.SUCCESS, "ip${…

如何进行远程debug?

文章目录 前言一、使用步骤1.首先通过nohup在启动jar包的我们可以添加参数:2.具体参数的含义如下:3. 查询监听的端口: 前言 在工作中,排查问题我们经常需要进行debug,而远程debug能够方便的帮助我们排查线上的问题。 …

【力扣】496. 下一个更大元素 I <单调栈、模拟>

【力扣】496. 下一个更大元素 I nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。给你两个没有重复元素的数组 nums1 和 nums2 &#xff0c;下标从 0 开始计数&#xff0c;其中nums1 是 nums2 的子集。   对于每个 0 < i <…

【AIGC】 国内版聊天GPT

国内版聊天GPT 引言一、国内平台二、简单体验2.1 提问2.2 角色扮演2.3 总结画图 引言 ChatGPT是OpenAI发开的聊天程序&#xff0c;功能强大&#xff0c;可快速获取信息&#xff0c;节省用户时间和精力&#xff0c;提供个性化的服务。目前国产ChatGPT&#xff0c;比如文心一言&a…

Kubernetes二进制部署方案

目录 一、环境准备 2.1、主机配置 2.2、安装 Docker 2.3、生成通信加密证书 2.3.1、生成 CA 证书&#xff08;所有主机操作&#xff09; 2.3.2、生成 Server 证书&#xff08;所有主机&#xff09; 2.3.3、生成 admin 证书(所有主机) 2.3.4、生成 proxy 证书 三、部署 …

JMeter接口自动化测试实例—JMeter引用javaScript

Jmeter提供了JSR223 PreProcessor前置处理器&#xff0c;通过该工具融合了Java 8 Nashorn 脚本引擎&#xff0c;可以执行js脚本以便对脚本进行前置处理。其中比较典型的应用就是通过执行js脚本对前端数据进行rsa加密&#xff0c;如登录密码加密。但在这里我就简单的应用javaScr…

java练习6. 求完数

题目: 请编程求出1000 以内的所有完数。 完数:一个数如果恰好等于它的所有真因子&#xff08;即除了自身外的所有因数&#xff09;之和&#xff0c;这个数就称为"完数"。 public static void main(String[] args) {for (int i 2; i < 1000; i) {int sum0;for (in…

ARM M33架构入门

概述 Arm Cortex-M33核心处理器专为需要高效安全或数字信号控制的物联网和嵌入式应用而设计。该处理器具有许多可选功能&#xff0c;包括数字信号处理扩展 (DSP)、用于硬件强制隔离的TrustZone 安全性、内存保护单元 (MPU)和浮点单元 (FPU)。 Cortex-M33 的性能比 Cortex-M…

【笔试题心得】关于正则的一些整理

本文部分内容摘抄整理自 正则表达式 – 教程 | 菜鸟教程 在笔试的过程中&#xff0c;也常常会对正则表达式进行考察&#xff0c;这里对正则表达式的常见用法&#xff0c;做一个学习和总结。 正则表达式的模式可以包括以下内容&#xff1a; 字面值字符&#xff1a;例如字母、数…

使用 Visual Studio GoogleTest编写 C/C++ 单元测试——入门篇

入门教程 Visual Studio 新建 GoogleTest项目&#xff0c;一路选默认参数 pch.h #pragma once#include "gtest/gtest.h"int add(int a, int b);pch.cpp #include "pch.h"int add(int a, int b) {return a b; }test.cpp #include "pch.h"TES…

Mac平台最佳PDF编辑软件,Qoppa PDF Studio Pro助您实现PDF文件的完美编辑

Qoppa PDF Studio Pro是一款功能强大的PDF编辑软件&#xff0c;现已推出Mac版本&#xff01;无论是个人用户还是企业用户&#xff0c;都能够从中受益。 Qoppa PDF Studio Pro为用户提供了一系列丰富的编辑工具&#xff0c;可以轻松地对PDF文件进行编辑、注释和标记。 用户可以…

【PACS源码】认识PACS的架构和工作流程

&#xff08;一&#xff09;PACS系统的组成及架构 PACS系统的基本组成部分包括&#xff1a;数字影像采集、通讯和网络、医学影像存储、医学影像管理、各类工作站五个部分。 而目前PACS系统的软件架构选型上看&#xff0c;主要有C/S和B/S两种形式。 C/S架构&#xff0c;即Client…

大数据平台是什么意思?有什么用?一般包含哪些模块?

大数据时代&#xff0c;还有很多人不知道大数据平台是什么意思&#xff1f;有什么用&#xff1f;一般包含哪些模块&#xff1f;今天我们就一起来简单了解一下吧&#xff01;仅供参考哦&#xff01; 大数据平台是什么意思&#xff1f;有什么用&#xff1f;一般包含哪些模块&am…

Java 项目日志实例基础:Log4j

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ 介绍几个日志使用方面的基础知识。 1 Log4j 1、Log4j 介绍 Log4j&#xff08;log for java&#xff09;是 Apache 的一个开源项目&#xff0c;通过使用 Log4j&#xff0c;我…

Visual Studio 2019源码编译cpu版本onnxruntime

1.下载onnxruntime源码 源码地址&#xff1a;gitee 》https://gitee.com/mirrors/onnx-runtime github 》https://github.com/microsoft/onnxruntime git clone --recursive https://gitee.com/mirrors/onnx-runtime 2.安装anaconda并配置python环境 安装anaconda时记得勾选默…

【C++深入浅出】初识C++中篇(引用、内联函数)

目录 一. 前言 二. 引用 2.1 引用的概念 2.2 引用的使用 2.3 引用的特性 2.4 常引用 2.5 引用的使用场景 2.6 传值、传引用效率比较 2.7 引用和指针的区别 三. 内联函数 3.1 内联函数的概念 3.2 内联函数的特性 一. 前言 上期说道&#xff0c;C是在C的基础之上&…
最新文章