您好,登錄后才能下訂單哦!
這篇“Unity的PSS/RSS/USS是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Unity的PSS/RSS/USS是什么”文章吧。
USS = 進程獨占的內存
RSS = USS + 共享內存
PSS = USS + 共享內存/共享這段內存的進程數量
所以,由于加上了共享內存,PSS的數值是非常不穩定的,和手機的系統和版本都有關系。由于共享內存還需要除以進程數,它甚至還和你安裝的軟件,和運行時后臺程序的數量相關……
因此,你家隨便一臺手機測試出來的PSS,和騰訊檢測時測出來的PSS很可能不同,也就不能死板地拿騰訊的標準對比。
正確的做法是,準備一個固定的測試環境,然后提交一個版本到騰訊,得出兩者PSS的差值。然后以后的本地測試都減去這個固定差值就行。
或者,用騰訊本家的游戲作為對比參考,比它們低就行。
騰訊的可以,憑啥你的就不行呢?
當一個進程被殺掉后,釋放出來的內存量是USS。
應用本身主動申請的所有內存,堆/棧/紋理數據等等都屬于private dirty,也就是USS。共享內存并不是公共庫這樣的概念,你使用公共庫,在公共庫的范圍創建了新的對象,那部分對象依然屬于USS。
共享內存在內存分配上有點類似“靜態數據”或者“代碼”,應用對它只能讀取而不能寫入。想要寫入就必須先復制一份到USS。所以按我們常規的對“內存分配”的理解,USS就是單個進程占用的內存的全部。
所以,用USS來判斷一個應用的內存占用才是科學的。我認為,PSS多出來的“share dirty / progress number”部分根本毫無意義。
安卓的任務管理器顯示的應用內存占用就是PSS。并不確定系統是否是以它作為管理基準。
USS在非Root的情況下,不能由外部進程獲得。有可能是當初為了檢測方便。
很多事情并沒有什么“為什么”,你只能接受。而且在孤立環境下PSS檢測確實問題不大,因為同一引擎同一時期開發的游戲,PSS比USS多出來的部分“大概”是個固定值,標準相應加上這個固定值就好了。
雖然控制內存的時候大部分情況用Unity自己的Profiler就行了——
但Unity確實不會統計所有的內存占用。我們可以確定,所有額外引入的C代碼庫它們自己申請的非托管內存都不會計算在內,其中就包括lua。另外,平臺渠道的架包它們自己申請的內存也不會計算在內。
如果只是自己控制內存的話,只看Unity的Profiler和Lua單獨的內存統計差不多就夠了。但是像渠道代碼,語音庫這類東西,雖然我們對它們無能為力,畢竟是捆綁在一起的,必須給它們挪出相應內存的空閑來,所以我們依然必須關心整個應用的內存占用(但Unity Profiler的結果同樣要關心,因為它才是普適的)
而比起用adb查看,能夠通過游戲界面呈現出來顯然更加便利。
應用內部獲得內存數據的辦法是 Debug.getMemoryInfo。
Debug.MemoryInfo localMemoryInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(localMemoryInfo); localMemoryInfo.getTotalPss(); localMemoryInfo.getTotalPrivateDirty();//USS
不編程的話,可以用adb工具查看
adb shell dumpsys meminfo 進程名
(注意結果里privte dirty就是USS)
主要是Debug時用來參考。考慮到運行效率,發布版本最好關閉這個功能。
但……它也可以幫助大家確保通過平臺PSS上限的檢測。與其擔心偶爾超過規定的PSS上限而畏手畏腳降低資源數量,不如放開手,然后在即將到達PSS上限的時候強行回收內存。實在不夠的時候,甚至可以禁止新資源加載,用空白物體取代,只保證游戲邏輯可以持續下去。
雖然這里只是為了應付檢測,但在實際游戲運行中,如果確實出現了內存不足的情況,這種“放棄游戲體驗”的做法也不失為一個辦法,畢竟總比應用崩掉要好。
獲取PSS/USS的數值并不能幫助我們做到這點。
——因為操作系統并不會因為一個進程占用了固定數量的內存而殺掉它(更不要說每個設備的內存總量還不一樣),操作系統只會在內存嚴重不足,也沒有后臺進程可殺的時候,才會為了保證系統安全而殺掉前臺進程。
所以,我們要做的就是在內存確實不夠的時候設法降低內存占用,乃至犧牲體驗。具體的做法就是:
執行GC
回收資源,刪除緩存,刪除預加載內容
降低畫質級別
以上皆無效,拒絕新資源的加載
要求用戶重啟應用
執行時機:
一個辦法是實時獲取當前系統剩余內存并處理
MemoryInfo:
availMem 當前系統剩余內存
threshold “低內存”的標準
lowMemory 當availMem<threshold即為true,這時候系統會開始關閉后臺應用
這段邏輯也可以用來驗證回收資源的成果,判斷是否要使用更激進的做法。
接受系統發出的內存警告提示
安卓:
onTrimMemory(int state)
當進程在前臺時,state的值可能是以下三個
TRIM_MEMORY_RUNNING_CRITICAL:內存不足(后臺進程不足3個)
TRIM_MEMORY_RUNNING_LOW:內存不足(后臺進程不足5個)
TRIM_MEMORY_RUNNING_MODERATE:內存不足(后臺進程超過5個)
這個事件觸發比較早,操作系統還可以關閉后臺進程來周轉。只是提醒在用戶內存的緊迫程度。
onLowMemory()
在所有后臺進程關閉后,同時處于lowMemory狀態時觸發。這時候系統已沒有內存騰挪的空間。剩余內存繼續變少,前臺應用隨時可能被關閉,以保障操作系統的正常運行(否則只能死機)
IOS:
- (void)didReceiveMemoryWarning
{
(int)OSMemoryNotificationCurrentLevel());
}
OSMemoryNotificationCurrentLevel()的枚舉:
OSMemoryNotificationLevelAny = -1 正常
OSMemoryNotificationLevelNormal = 0 正常
OSMemoryNotificationLevelWarning = 1 內存不足警告
OSMemoryNotificationLevelUrgent = 2 嚴重內存不足警告
OSMemoryNotificationLevelCritical = 3 閃退(所以實際上無法收到此消息)
OSMemoryNotificationLevelWarning可以認為等效onTrimMemory(TRIM_MEMORY_RUNNING_CRITICAL),只是提示出現內存不足的現象,這時候會通過關閉后臺進程來獲取額外內存,并不一定非要處理。
OSMemoryNotificationLevelUrgent 可以認為等效onLowMemory,表示系統已經處于非常危險的狀態,前臺進程隨時都可能被關閉。
在Unity 5.6之后,提供了系統事件Application.lowMemory,相當于:
- iOS: [UIApplicationDelegate applicationDidReceiveMemoryWarning]
- Android: onLowMemory() and onTrimMemory(level == TRIM_MEMORY_RUNNING_CRITICAL)
當內存出現警告時,并不代表必須要馬上執行縮減內存的操作,因為這些操作都是有代價的,僅僅是頻繁地GC就會導致游戲體驗的極大下降,而這是有可能在不閃退的前提下避免的。
系統給出的內存不足提示本身是為App準備的,如果你在瀏覽網頁過程中彈出了支付寶,顯然,你并不希望在支付寶運行過程中把網頁的進程殺掉。當內存不足,網頁進程要被殺掉前,系統就會給支付寶發一個提示,希望它也能停止申請內存,以便給網頁進程保活。
從App的角度,每個應用都應該盡可能共存,內存警告系統也是這樣設計的。但是游戲則不同。對于玩家而言,進入游戲把后臺的網頁殺掉不僅沒有關系,也是預期會發生的事。畢竟現在也不興玩游戲前“清除內存加速球”之類的玩意兒了。
我進游戲前開了幾個應用,我沒有強關他們,然后我進游戲,游戲為了不殺掉他們卻要強行縮減自己的內存降低畫質讓游戲變卡??
這不是自找沒趣么?
不過,從實際結果來看,當到了OSMemoryNotificationLevelWarning,onTrimMemory(level == TRIM_MEMORY_RUNNING_CRITICAL),也就是Unity的Application.lowMemory的觸發點的時候,應用確實已經處于較為危險的地步。雖然游戲還可以正常運行,后臺進程大多已經關閉,切回桌面也需要重新啟動,甚至來個電話收個短信都可能導致游戲被關閉。雖然可能不至于閃退,體驗已經變得不好。
個人建議,這個提示出現后只進行對體驗影響較小的處理。
如果連續出現,則加大處理的力度。
但如果連onLowMemory,OSMemoryNotificationLevelUrgent都已經被觸發了,則必須不計一切代價將內存降低下去,不處理是真的要完蛋的。
此外,onLowMemory,OSMemoryNotificationLevelUrgent在內存申請較快的情況是可能不出現便直接閃退的,它們并不保險。這點在場景加載過程極易發生,所以在加載過程時對內存警告的處理就要更加保守。而在內存較為平穩的階段,就可以稍微倦怠一些,等待onLowMemory出現后再處理。
然而這些做法其實無異于在刀尖上跳舞,可以的話,還是要盡力將內存降低下去,應用切換的體驗也是有必要保證的。切出游戲便無法回來,玩家的體驗并不好。
然而如果有平臺的PSS限制的話……因為他們的限制往往過于求穩,出現Application.lowMemory(甚至在之前)恐怕就必須清理內存才能滿足他們的要求,也就不用考慮那么多了。
以上就是關于“Unity的PSS/RSS/USS是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。