1. 程式人生 > >LayaAir引擎學習日誌14----LayaAir記憶體優化的問題

LayaAir引擎學習日誌14----LayaAir記憶體優化的問題

物件池

物件池,涉及到不斷重複使用物件。在初始化應用程式期間建立一定數量的物件並將其儲存在一個池中。對一個物件完成操作後,將該物件放回到池中,在需要新物件時可以對其進行檢索。

由於例項化物件成本很高,使用物件池重用物件可減少例項化物件的需求。還可以減少垃圾回收器執行的機會,從而提高程式的執行速度。

以下程式碼演示使用Laya.utils.Pool:

1 2 3 4 5 6 7 8 9 10 11 12 var SPRITE_SIGN = 'spriteSign'
; var sprites = []; function initialize() { for (var i = 0; i < 1000; i++) { var sp = Pool.getItemByClass(SPRITE_SIGN, Sprite) sprites.push(sp); Laya.stage.addChild(sp); } } initialize();

在initialize中建立大小為1000的物件池。

以下程式碼在當單擊滑鼠時,將刪除顯示列表中的所有顯示物件,並在以後的其他任務中重複使用這些物件:

1 2 3 4 5 6 7 8 9 10 Laya.stage.on("click"thisfunction() { var sp; for(var i = 0, len = sprites.length; i < len; i++) { sp = sprites.pop(); Pool.recover(SPRITE_SIGN, sp); Laya.stage.removeChild(sp); } });

呼叫Pool.recover後,指定的物件會被回收至池內。

使用Handler.create

在開發過程中,會經常使用Handler來完成非同步回撥。Handler.create使用了內建物件池管理,因此在使用Handler物件時應使用Handler.create來建立回撥處理器。以下程式碼使用Handler.create建立載入的回撥處理器:

1 Laya.loader.load(urls, Handler.create(this, onAssetLoaded));

在上面的程式碼中,回撥被執行後Handler將會被物件池收回。此時,考慮如下程式碼會發生什麼事:

1 Laya.loader.load(urls, Handler.create(this, onAssetLoaded), Handler.create(this, onLoading));

在上面的程式碼中,使用Handler.create返回的處理器處理progress事件。此時的回撥執行一次之後就被物件池回收,於是progress事件只觸發了一次,此時需要將四個名為once的引數設定為false:

1 Laya.loader.load(urls, Handler.create(this, onAssetLoaded), Handler.create(this, onLoading, nullfalse));

釋放記憶體

JavaScript執行時無法啟動垃圾回收器。要確保一個物件能夠被回收,請刪除對該物件的所有引用。Sprite提供的destory會幫助設定內部引用為null。

例如,以下程式碼確保物件能夠被作為垃圾回收:

1 2 var sp = new Sprite(); sp.destroy();

當物件設定為null,不會立即將其從記憶體中刪除。只有系統認為記憶體足夠低時,垃圾回收器才會執行。記憶體分配(而不是物件刪除)會觸發垃圾回收。

垃圾回收期間可能佔用大量CPU並影響效能。通過重用物件,嘗試限制使用垃圾回收。此外,儘可能將引用設定為null,以便垃圾回收器用較少時間來查詢物件。有時(比如兩個物件相互引用),無法同時設定兩個引用為null,垃圾回收器將掃描無法被訪問到的物件,並將其清除,這會比引用計數更消耗效能。

資源解除安裝

遊戲執行時總會載入許多資源,這些資源在使用完成後應及時解除安裝,否則一直殘留在記憶體中。

下例演示載入資源後對比資源解除安裝前和解除安裝後的資源狀態:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var assets = []; assets.push("res/apes/monkey0.png"); assets.push("res/apes/monkey1.png"); assets.push("res/apes/monkey2.png"); assets.push("res/apes/monkey3.png"); Laya.loader.load(assets, Handler.create(this, onAssetsLoaded)); function onAssetsLoaded() { for(var i = 0, len = assets.length; i < len; ++i) { var asset = assets[i]; console.log(Laya.loader.getRes(asset)); Laya.loader.clearRes(asset); console.log(Laya.loader.getRes(asset)); } }

關於濾鏡、遮罩

嘗試儘量減少使用濾鏡效果。將濾鏡(BlurFilter和GlowFilter)應用於顯示物件時,執行時將在記憶體中建立兩張點陣圖。其中每個點陣圖的大小與顯示物件相同。將第一個點陣圖建立為顯示物件的柵格化版本,然後用於生成應用濾鏡的另一個位圖:

   圖片1.png

應用濾鏡時記憶體中的兩個點陣圖

當修改濾鏡的某個屬性或者顯示物件時,記憶體中的兩個點陣圖都將更新以建立生成的點陣圖,這兩個點陣圖可能會佔用大量記憶體。此外,此過程涉及CPU計算,動態更新時將會降低效能(參見“圖形渲染效能 – 關於cacheAs)。

ColorFiter在Canvas渲染下需要計算每個畫素點,而在WebGL下的GPU消耗可以忽略不計。

最佳的做法是,儘可能使用影象創作工具建立的點陣圖來模擬濾鏡。避免在執行時中建立動態點陣圖,可以幫助減少CPU或GPU負載。特別是一張應用了濾鏡並且不會在修改的影象。

優化Sprite

1. 儘量減少不必要的層次巢狀,減少Sprite數量。

2. 非可見區域的物件儘量從顯示列表移除或者設定visible=false。

3. 對於容器內有大量靜態內容或者不經常變化的內容(比如按鈕),可以對整個容器設定cacheAs屬性,能大量減少Sprite的數量,顯著提高效能。如果有動態內容,最好和靜態內容分開,以便只快取靜態內容。

4. Panel內,會針對panel區域外的直接子物件(子物件的子物件判斷不了)進行不渲染處理,超出panel區域的子物件是不產生消耗的。

優化DrawCall

1. 對複雜靜態內容設定cacheAs,能大量減少DrawCall,使用好cacheAs是遊戲優化的關鍵。

2. 儘量保證同圖集的圖片渲染順序是挨著的,如果不同圖集交叉渲染,會增加DrawCall數量。

3. 儘量保證同一個面板中的所有資源用一個圖集,這樣能減少提交批次。

優化Canvas

      在對Canvas優化時,我們需要注意,在以下場合不要使用cacheAs:

1. 物件非常簡單,比如一個字或者一個圖片,設定cacheAs="bitmap"不但不提高效能,反而會損失效能。

2. 容器內有經常變化的內容,比如容器內有一個動畫或者倒計時,如果再對這個容器設定cacheAs="bitmap",會損失效能。

可以通過檢視Canvas統計資訊的第一個值,判斷是否一直在重新整理Canvas快取。

關於cacheAs

設定cacheAs可將顯示物件快取為靜態影象,當cacheAs時,子物件發生變化,會自動重新快取,同時也可以手動呼叫reCache方法更新快取。 建議把不經常變化的複雜內容,快取為靜態影象,能極大提高渲染效能,cacheAs有"none","normal"和"bitmap"三個值可選。

1. 預設為"none",不做任何快取。

2. 當值為"normal"時,Canvas下進行畫布快取,webgl模式下進行命令快取。

3. 當值為"bitmap"時,Canvas下進行依然是畫布快取,webGL模式下使用renderTarget快取。這裡需要注意的是,webGL下renderTarget快取模式有2048大小限制,超出2048會額外增加記憶體開銷。另外,不斷重繪時開銷也比較大,但是會減少drawcall,渲染效能最高。 webGL下命令快取模式只會減少節點遍歷及命令組織,不會減少drawcall,效能中等。

設定cacheAs後,還可以設定staticCache=true以阻止自動更新快取,同時可以手動呼叫reCache方法更新快取。

        cacheAs主要通過兩方面提升效能。一是減少節點遍歷和頂點計算;二是減少drawCall。善用cacheAs將是引擎優化效能的利器。

        下例繪製10000個文字:

1 2 3 4 5 6 7 8 9 10 11 12

相關推薦

LayaAir引擎學習日誌14----LayaAir記憶體優化的問題

物件池 物件池,涉及到不斷重複使用物件。在初始化應用程式期間建立一定數量的物件並將其儲存在一個池中。對一個物件完成操作後,將該物件放回到池中,在需要新物件時可以對其進行檢索。 由於例項化物件成本很高,使用物件池重用物件可減少例項化物件的需求。還可以減少

LayaAir引擎學習日誌15----LayaAir記憶體效能分析

效能分析器(Profiles)         效能分析器(Profiles)是 chrome 開發者工具的一部分,可以通過在頁面右鍵選擇審查元素或在谷歌瀏覽器頁面按F12 開啟 chrome 開發者工具。然後點選 Profiles 切換至效能分析器(Profiles)

Java學習日誌14.15 (第一階段基礎)

2018.10.31 16:48 夕陽西下 14.15_常見物件(BigDecimal類的概述和方法使用) A:BigDecimal的概述 由於在運算的時候,float型別和double很容易丟失精度,演示案例。 所以,為了能精確的表示、計算浮點

Java學習日誌14.14(第一階段基礎)

2018.10.30 23:34 14.14_常見物件(BigInteger類的概述和方法使用) ** A:BigInteger的概述 * 可以讓超過Integer範圍內的資料進行運算 B:構造方法 public BigInteger(String v

Java學習日誌14.13(第一階段基礎)

2018.10.30 9:56 晴 14.13_常見物件(System類的概述和方法使用) A:System類的概述 public final class System extends Object System 類包含一些有用的類欄位和方法。它不能

Java學習日誌14.12(第一階段基礎)

2018.10.29 晚22.58 14.12_常見物件(Random類的概述和方法使用) A:Random類的概述 *此類用於產生隨機數如果用相同的種子建立兩個 Random 例項, 則對每個例項進行相同的方法呼叫序列,它們將生成並返回相同的數字序列。 此類的例項

Java學習日誌14.11(第一階段基礎)

2018.10.24 下午陰 14.11_常見物件(Math類概述和方法使用) 學習知識: A:Math類概述 * Math 類包含用於執行基本數學運算的方法,如初等指數、對數、平方根 和 三角函式。 B:成員方法 * public static int abs(int a) * /

Java學習日誌14.09(第一階段基礎)

2018.10.24 晴 14.09_常見物件(Pattern和Matcher的概述) java.util.regex.Pattern Pattern 正則表示式的編譯表示形式。 指定為字串的正則表示式必須首先被編譯為此類的例項。然後,可將得到的模式用於建立 Matcher

Java學習日誌14.3 (第一階段基礎)

2018.10.23 天氣陰 黑馬程式設計師養成記錄第3天 5_常見物件(正則表示式的分割功能) 新知識梗概: 正則表示式的分割功能 String類的功能:public String[] split(String regex) 根據匹配給定的正則表示式來拆分此字串 返回型別:Stri

Java學習日誌14.2 (第一階段基礎)

2018.10.22 天氣:晴 黑馬程式設計師養成記錄第二天 3.常見物件(數量詞) Greedy 數量詞 * X? X,一次或一次也沒有 * X X,零次或多次 * X+ X,一次或多次 * X{n} X,恰好 n 次 * X{n,} X,至少 n 次 * X{n,m} X,至少

Java學習日誌14.1(第一階段基礎)

**2018.10.20 陰 黑馬程式設計師養成記錄第一天 * 正則表示式:* *定義:一個用來描述或者匹配一系列符合某個語法規則的字串的單個字串。 *作用:比如註冊郵箱,郵箱有使用者名稱和密碼,一般會對其限制長度,這個長度的事情就是正則表示式做的。 1.常見

Java學習日誌14.19(第一階段基礎)

2018.11.3 23:40 14.19_常見物件(Calendar類的概述和獲取日期的方法)(掌握) *A:Calendar類的概述 * Calendar 類是一個抽象類,它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日曆欄位之間的轉換提供了

Java學習日誌14.16(第一階段基礎)

2018.11.1 11:06 陰 14.16_常見物件(Date類的概述和方法使用)(掌握) ** * A:Date類的概述 * 類 Date 表示特定的瞬間,精確到毫秒。 B:構造方法 public Date() 分配 Date 物件並初

Java學習日誌14.3 (第一階段基礎)

2018.10.23 天氣陰 黑馬程式設計師養成記錄第3天 5_常見物件(正則表示式的分割功能) 新知識梗概: 正則表示式的分割功能 String類的功能:public String[] split(String regex) 根據匹配給定的正則表示式來拆分此字

Egert白鷺引擎學習日誌02

從Hello World開始 1.開啟Egret Launcher ,新建一個EUI專案,取名test01 選擇擴充套件庫預設就可以 點選建立專案!在 Wing 的左上角可以看到有我們專案的目錄結構: 2.點選檔案 src目錄 Main.ts 找到cr

Egret白鷺引擎學習日誌01

1.簡介 egret是一個開源免費的遊戲框架,它使用TypeScript指令碼語言進行開發; 2.下載安裝包 下載完成後根據提示進行安裝​ 根據自己需求進行安裝相應版本 3.下載工具 根據需求下載相應工具,我學習開始下載的工具也就是圖下已安裝的工具

layaAir引擎制作遊戲的圖集動畫、時間軸動畫、和骨骼動畫總結二

var 拖拽 資源 轉化 post 類型 amp 按鈕動畫 let 一、角色序列幀.ani動畫的制作 1、在項目管理器中創建動畫文件 2.創建動畫模板,編輯動效名稱 3.編輯序列幀動畫 .ani格式動畫的代碼控制 1.動畫加載loadAnmition() 2.播放與停止、動

MySQL基礎入門學習14】存儲引擎

nsis ont 過程 關系 ali 余額 bili 事務 atom 查看數據表的創建命令: 【存儲引擎】: MySQL可以將數據以不同的奇數存儲在文件(內存)中,這種技術就成為存儲引擎        每一種存儲引擎都使用了不同的存儲機制、索引技巧、鎖定水平,最

記憶體管理函式(C++學習筆記 14

一、C語言中的記憶體管理函式 記憶體分配函式主要有malloc( )和calloc( ),記憶體釋放函式是free( )。 這兩類函式的原型在stdlib.h中,要使用這些函式時,首先要用檔案包含: #include"stdlib.h" 或#include<stdli

Java學習14天—陣列高階應用—比較排序及其優化

 比較排序 比較排序:compare(選擇排序:select) 原理:依次拿某個位置上的元素和其後的所有元素比較,大的放後邊,每次確定的就是此位置上的元素.比較的趟數是元素個數減1 package com.nim.sort; /* * 比較排序及其優化 */ pu