您當前的位置:首頁 > 遊戲

Unity —— 快取池簡單理解

作者:由 阿離 發表于 遊戲時間:2022-10-16

來理解快取池之前,我們先了解一下

C#的記憶體回收機制

每次例項化一個物件(在場景上建立一個物件),都會分配一個記憶體空間;

當這個物件被刪除時,僅僅時斷開了對這片空間的引用,此記憶體空間並沒有被釋放掉。

再次建立物件時,會繼續分配其他的記憶體空間,直到記憶體被全部被分配滿。

當記憶體滿了再回過頭看有哪些是不用的“垃圾”,再回收釋放。

這樣的一次釋放,叫做 “

一次GC

”。

所謂垃圾,就是沒有被任何變數、物件引用的內容。

透過是否被引用來確定哪些物件是“垃圾”。

Unity —— 快取池簡單理解

一次GC

正是因為每次GC需要經過大量的計算來判斷是否需要回收,對CPU的消耗較大,所以每次GC都可能會造成卡頓,GC次數一旦多了會嚴重影響玩家的使用體驗,由此出現了

快取池

可以把快取池想象成一個衣櫃:

當我們要穿一件衣服(使用一個物件)時,先去衣櫃中看有沒有這件衣服;

如果沒有,我們去買一件(建立一個物件),並放到衣櫃中可以下次使用;

如果有,直接穿這件衣服(使用這個物件),用完後再放回衣櫃(快取池),不丟棄。

每個衣櫃都有很多的格子,裡面分類裝著衣服、褲子、帽子、襪子等(不同的物件型別);

從買衣服到穿衣服都要分門別類放好,每次使用從對應的格子中取出。

如何實現快取池模組呢?

這裡需要用到兩個知識點:

Dictionary List

GameObject 和 Resources 兩個公共類中的API

下面是最簡單的快取池:

public

class

PoolMgr

BaseManager

<

PoolMgr

>

{

//宣告快取池容器

public

Dictionary

<

string

List

<

GameObject

>>

poolDic

=

new

Dictionary

<

string

List

<

GameObject

>>();

//取資源

public

GameObject

GetObject

string

name

//從哪個格子中取資源

{

GameObject

obj

=

null

//這個格子存在且不為空

if

poolDic

ContainsKey

name

&&

poolDic

ContainsKey

>

0

{

obj

=

poolDic

name

][

0

];

//找到這個資源

poolDic

name

]。

RemoveAt0

0

);

//取出(釋放空間)

}

else

{

//格子中沒有這個資源 例項化一個物件 返回出去

obj

=

GameObject

Instantiate

Resources

Load

<

GameObject

>(

name

));

obj

name

=

name

//把物件名改成和格子同名

}

obj

SetActive

true

);

//啟用,使其顯示

return

obj

}

//還資源

public

void

PushObject

string

name

GameObject

obj

//還到哪個格子裡,還的東西是什麼

{

obj

SetActive

false

);

//失活,使其隱藏

//裡面有格子

if

poolDic

ContainsKey

name

))

{

poolDic

name

Add

obj

);

}

//裡面沒有格子

else

{

//建立一個格子並新增

poolDic

Add

name

new

List

<

GameObject

>(){

obj

});

}

}

}

快取池的特點:

表面上固定佔用資源不釋放會造成記憶體的浪費

實際上減少了GC的次數,每次記憶體用滿都會GC一次,用了快取池後不用重複的建立、刪除,提高CPU的效能。

標簽: name  快取  poolDic  格子  GC