遊戲設計模式——內存池管理

對C++遊戲程序員來說,內存管理是一件相當頭疼的問題。因為C++是將內存赤裸裸的交給程序員,而不像Java/C#有gc機制。

好處是這樣對於高性能要求的遊戲程序,原生的內存分配可以避免gc機制的臃腫操作,從而大大提高性能。

壞處是C++程序員得時時警惕內存問題:

內存洩露問題

do{
 T* object = new T();
}while(0);

上面的例子中。忘記回收內存,函數退棧導致丟失了object指針,就再也找回不了new的內存地址,這時內存一直就會被佔用著。

內存洩漏很容易理解,不作多講。

內存碎片問題

由於對堆內存的分配/釋放的順序是隨機的,導致申請的內存塊隨機分佈於原始內存,倘若分佈不是連續的(隨機順序往往導致多個內存塊都是相隔開的),那麼便會產生“洞”。

遊戲設計模式——內存池管理

隨著時間推移,堆內存越來越多出現這些“洞”,導致可用的自由內存塊被拆分成多個小內存塊。

這就導致即使有足夠的自由內存,分配請求仍然可能會失敗。

遊戲設計模式——內存池管理

內存頁切換問題

虛擬內存系統把不連續的物理內存塊(即內存頁)映射至虛擬地址空間,使內存頁對於應用程序來說看上去是連續的。

在支持虛擬內存的操作系統上,多次使用原生C/C++內存分配,有可能其中幾次是一個內存頁,幾次是第二個內存頁,又有幾次是第三個內存頁的內容....在重複共同使用這些內存的時候有可能導致昂貴的切換內存頁開銷。

一些本世代遊戲機雖然技術上支持虛擬內存,但由於其導致的開銷,多數遊戲引擎不會使用虛擬內存。

遊戲設計模式——內存池管理

內存池(Memory Pool)

對C++內存分配進行適合當前程序的封裝就顯得尤為重要,這樣C++程序員就能在封裝完內存機制後減少大量心思警惕內存問題。

而如何封裝還能高效的使用內存,就成了一門學問——內存池管理。

而內存池是什麼:

預先通過new或者malloc(原生的內存分配函數)分配好一個大塊內存(挖好池子),然後提供這塊內存池的再分配函數。

當程序員需要分配小塊堆內存時,可以向這個內存池請求分配小內存。

  • 由於內存池本身往往內存比較大,所以內存池本身的分配釋放不易產生內存碎片。
  • 即使程序員由於操作失誤導致內存池內部出現內存碎片或者內存洩漏問題,但是整個內存池本身只要正確釋放,內存問題就不會向外擴張。
  • 一次性分配好大內存,儘可能減少了多次分配可能導致的過多物理內存頁,從而減少了切換內存頁開銷。

關注小編,更多IT技術第一時間奉上!

遊戲設計模式——內存池管理


分享到:


相關文章: