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.pswp.cn/news/40152.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40152.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40152.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Rabbitmq消息不丟失

目錄 一、消息不丟失1.消息確認2.消息確認業務封裝2.1 發送確認消息測試2.2 消息發送失敗,設置重發機制 一、消息不丟失 消息的不丟失,在MQ角度考慮,一般有三種途徑: 1,生產者不丟數據 2,MQ服務器不丟數據…

設計HTML5列表和超鏈接

在網頁中,大部分信息都是列表結構,如菜單欄、圖文列表、分類導航、新聞列表、欄目列表等。HTML5定義了一套列表標簽,通過列表結構實現對網頁信息的合理排版。另外,網頁中還包含大量超鏈接,通過它實現網頁、位置的跳轉&…

C語言“牽手”微店商品詳情數據方法,微店商品詳情API接口申請指南

微店平臺的商品詳情通常包括以下信息: 商品名稱:展示商品的名稱,用于描述商品的特性和分類。 商品圖片:展示商品的圖片,可以有多張圖片以展示不同角度和細節。 商品價格:顯示商品的銷售價格,可…

nodejs服務后臺持續運行三種方法

nodejs服務后臺持續運行三種方法 一、利用 forever 推薦 forever是一個nodejs守護進程,完全由命令行操控。forever會監控nodejs服務,并在服務掛掉后進行重啟。 1、安裝 forever npm install forever -g 2、啟動服務 service forever start 3、使用…

小程序CSS button按鈕自定義高度之后不居中

問題&#xff1a; 按鈕設置高度后不居中 <view><button class"btn1" size"">Save</button> </view> page {font-size: 30rpx; }.btn1 {margin-top: 100rpx;height: 190rpx;background: linear-gradient(90deg, #FF8A06, #FF571…

Wi-Fi 安全在學校中的重要性

Wi-Fi 是教育機構的基礎設施&#xff0c;從在線家庭作業門戶到虛擬教師會議&#xff0c;應有盡有。大多數 K-12 管理員對自己的 Wi-Fi 網絡的安全性充滿信心&#xff0c;并認為他們現有的網絡安全措施已經足夠。 不幸的是&#xff0c;這種信心往往是錯誤的。Wi-Fi 安全雖然經常…

【數據結構OJ題】鏈表中倒數第k個結點

原題鏈接&#xff1a;https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId13&&tqId11167&rp2&ru/activity/oj&qru/ta/coding-interviews/question-ranking 目錄 1. 題目描述 2. 思路分析 3. 代碼實現 1. 題目描述 2. 思路分析 …

VectorStyler for Mac: 讓你的創意無限綻放的全新設計工具

VectorStyler for Mac是一款專為Mac用戶打造的矢量設計工具&#xff0c;它結合了功能強大的矢量編輯器和創意無限的樣式編輯器&#xff0c;讓你的創意無限綻放。 VectorStyler for Mac擁有直觀簡潔的用戶界面&#xff0c;讓你能夠輕松上手。它提供了豐富的矢量繪圖工具&#x…

JavaWeb博客項目--推薦算法--完整代碼及思路

基于用戶的協同過濾算法&#xff08;UserCF&#xff09; 因為我寫的是博客項目&#xff0c;博客數量可能比用戶數量還多 所以選擇基于用戶的協同過濾算法 重要思想 當要向用戶u進行推薦時&#xff0c;我們先找出與用戶u最相似的幾個用戶&#xff0c;再從這幾個用戶的喜歡的物…

數據可視化和數字孿生相互促進的關系

數據可視化和數字孿生是當今數字化時代中備受關注的兩大領域&#xff0c;它們在不同層面和領域為我們提供了深入洞察和智能決策的機會&#xff0c;隨著兩種技術的不斷融合發展&#xff0c;很多人會將他們聯系在一起&#xff0c;本文就帶大家淺談一下二者之間相愛相殺的關系。 …

Springboot集成ip2region離線IP地名映射-修訂版

title: Springboot集成ip2region離線IP地名映射 date: 2020-12-16 11:15:34 categories: springboot description: Springboot集成ip2region離線IP地名映射 1. 背景2. 集成 2.1. 步驟2.2. 樣例2.3. 響應實例DataBlock2.4. 響應實例RegionAddress 3. 打開瀏覽器4. 源碼地址&…

OpenShift 4 - 基于 MinIO 安裝 Red Hat Quay 鏡像倉庫

《OpenShift / RHEL / DevSecOps 匯總目錄》 說明&#xff1a;本文已經在 OpenShift 4.13 Quay 3.9 的環境中驗證 本文適合在單機 OpenShift 環境安裝 Red Hat Quay 鏡像倉庫。 另外《OpenShift 4 - 安裝 ODF 并部署紅帽 Quay (1 Worker)》也可以在單節點部署。 而《OpenShif…

前后端分離------后端創建筆記(11)用戶刪除

B站視頻&#xff1a;30-用戶刪除&結束語_嗶哩嗶哩_bilibili 1、現在我們要做一個刪除的功能 1.1 首先做一個刪除的功能接口&#xff0c;第一步先來到后端&#xff0c;做一個刪除的接口 2、刪除我們用Delete請求 3、方法名我給他改一下 3.1這里給他調一下刪除方法&#xf…

Java 中 List 集合排序方法

方式一&#xff1a; 調用List接口自己的sort方法排序 public static void main(String[] args) {List<Integer> numListnew ArrayList<>();numList.add(999);numList.add(123);numList.add(456);numList.add(66);numList.add(9);Collections.sort(numList); //使…

在一小時內構建您的深度學習應用程序

一、說明 我已經做了將近十年的數據分析。有時&#xff0c;我使用機器學習技術從數據中獲取見解&#xff0c;并且我習慣于使用經典 ML。 雖然我已經通過了神經網絡和深度學習的一些MOOC&#xff0c;但我從未在我的工作中使用過它們&#xff0c;這個領域對我來說似乎很有挑戰性。…

【Leetcode】91.解碼方法

一、題目 1、題目描述 一條包含字母 A-Z 的消息通過以下映射進行了 編碼 : A -> "1" B -> "2" ... Z -> "26"要 解碼 已編碼的消息,所有數字必須基于上述映射的方法,反向映射回字母(可能有多種方法)。例如,"11106" …

智能數據建模軟件DTEmpower 2023R2新版本功能介紹

DTEmpower是由天洑軟件自主研發的一款通用的智能數據建模軟件&#xff0c;致力于幫助工程師及工科專業學生&#xff0c;利用工業領域中的仿真、試驗、測量等各類數據進行挖掘分析&#xff0c;建立高質量的數據模型&#xff0c;實現快速設計評估、實時仿真預測、系統參數預警、設…

機器學習深度學習——自注意力和位置編碼(數學推導+代碼實現)

&#x1f468;?&#x1f393;作者簡介&#xff1a;一位即將上大四&#xff0c;正專攻機器學習的保研er &#x1f30c;上期文章&#xff1a;機器學習&&深度學習——注意力分數&#xff08;詳細數學推導代碼實現&#xff09; &#x1f4da;訂閱專欄&#xff1a;機器學習…

Cat(2):下載與安裝

1 github源碼下載 要安裝CAT&#xff0c;首先需要從github上下載最新版本的源碼。 官方給出的建議如下&#xff1a; 注意cat的3.0代碼分支更新都發布在master上&#xff0c;包括最新文檔也都是這個分支注意文檔請用最新master里面的代碼文檔作為標準&#xff0c;一些開源網站…