遊戲開發者需要注意的4個內存使用問題

作者:Aditya Kulkarni

從銷售角度來看,你的全新手機遊戲總是應該適用於今天人們所使用的大多數設備。“大多數設備”可能會讓開發者感到驚訝。在2015年1月,世界各地的手機用戶數已經達到36億人。所以開發者的工作便是讓遊戲/應用能夠適應這些設備的種種硬件約束條件。開發者們在開發像遊戲等需要耗費內存的軟件時需要進行更多思考。通過編寫這篇文章,我希望能夠幫助一些不瞭解技術的人進一步理解一些內存問題,而這也是他們在致力於2D遊戲項目時需要考慮的內容。

1)內存泄露:內存泄露指的是未被釋放的分配內存塊。

類比:讓我們想象你在一個擁有3個方形儲物櫃的房間尋找一個儲物櫃。

lockers(from gamecareerguide)

lockers(from gamecareerguide)

1.John和Danny“需要”儲存自己的裝備,而一個儲物櫃便足以滿足他們每個人。所以現在我們擁有2個已被使用的儲物櫃,以及1個閒置的儲物櫃。

2.這時候John需要儲存他的頭盔,並且不再需要他之前儲存的裝備。所以現在最理想的情況是他應該拿出之前的裝備並將頭盔裝進去。但是他卻向管理者請求另一個儲物櫃並希望將頭盔放在全新儲物櫃中。從邏輯上看,在這之後所有的儲物櫃便都滿了。而現在的John會忘記自己儲存在第一個儲物櫃中的裝備。

3.現在Danny需要儲存2個頭盔並需要2個儲物櫃,所以他決定拿掉自己的裝備並空出1個儲物櫃。然後他向管理者申請了一個新的儲物櫃,但是因爲所有儲物櫃都滿了所以遭到了管理者的拒絕。

在這裏,即使John從儲物櫃中拿掉無用的裝備,Danny也不能再使用多出來的儲存空間。

2)相同紋理的多個例子:一個紋理將佔用寬度*高度*4(遊戲邦注:紅色,綠色,藍色和透明度各佔據1個字節)的儲存空間。所以一張512×512規格的圖像將佔據1.05兆的內存。而同樣的紋理將佔據其3倍的儲存空間,也就是3.15兆。所以如果我們想要使用這些圖像作爲紋理的話我們便需要準備多出3倍的內存。

類比:讓我們以一張呈現出你最喜歡的角色“buttman”並且不能無限次使用的方形貼紙爲例。

sticker(from gamecareerguide)

sticker(from gamecareerguide)

你需要將這個新角色呈現給3個不同的人。所以你能夠:

1.獲得2張一樣的貼紙,獲得3個木質框架能夠在上面貼貼紙,並且你將把這些木製框架遞交給那3個人。

2.讓那3個人去獲得屬於自己的木製框架並讓他們將貼紙貼到框架上。

第2個例子適合我們,因爲我們可以反覆使用同樣的貼紙。這也適用於軟件程序中,即所有人可以同時想到buttman。

3)不必要的迭代:比起多次調用,在資源中調用for/while循環更簡單。你可以在一個循環中處理多個任務。

類比:你是一個間諜,並需要向3個遙遠的不同場所運輸包裹。並且你需要從這3個不同場所的不同boss那收集到重要的祕密信息。

因爲你是從不同boss那接到這些任務,所以你可以:

1.根據不同boss去分配你的任務。例如你可以駕車前往所有的這3個場所並先完成boss A所分配的任務,然後再駕車前往同樣的3個場所完成Boss B所分配的任務。反之亦然。

2.根據不同場所去分配你的任務。例如你可以先駕車前往第一個場所,遞交包裹並獲得信息,然後再駕車前往下個場所。

如果你所制定的任務計劃是像第1種情況那樣的話你便是一個愚蠢的間諜,因爲你需要花費更多時間和資源去完成同樣的任務。

4)在內存中保留未使用的對象:任何時候都只有一定的對象能夠被使用或出現在屏幕上。因爲我們擁有優先的內存空間,所以任何被留在內存裏的額外對象都是在耗費資源。

類比:你需要將一輛馬車從A點推到B點。讓我們假設如果馬車未負載任何東西或者載着最輕的東西,這便是一個較簡單的任務。但是因爲你喜歡啤酒,所以你選擇用馬車去載一桶啤酒,從而加重了自己任務的難度。

所以在這裏的最佳解決方法便是放棄你所深愛的啤酒。

這裏所列出的問題絕對超過我在一篇文章中能夠寫下的內容。作爲一名開發者,你應該儘快識別這些問題並使用有效的解決方法。先克服這些挑戰再發行產品是真正讓人興奮的遊戲開發過程。每個人每一天只擁有24個小時。對於我們而言,人們能夠花費這些寶貴的時間去嘗試我們所創造的內容便是推動着我們去開發遊戲的最佳動力。

本文爲遊戲邦/gamerboom.com編譯,拒絕任何不保留版權的轉發,如需轉載請聯繫:遊戲邦

Four Memory Problems to Watch Out for in Game Development
[08.20.15]

– Aditya Kulkarni

From a sales point of view, your cool new mobile game should work on most of the devices used by people today. The term ‘most of the devices’ evokes a ‘yikes’ by a developer. As of Jan 2015, the number of unique mobile users was 3.6 Billion. It’s the job of the developer to make the game/application work within the hardware constraints of a lot of those devices. Developers need to put a lot of thought while developing memory intensive software like games. By writing this article, I hope to help a non-tech person understand some of the memory problems that should be taken into account when developing 2D game projects.

1) Memory Leak: A memory leak can be defined as an allocated memory block which has not been released.

Analogy: Let’s imagine a cabinet that you find in a locker room having a total of 3 perfectly square lockers.

1.John and Danny ‘need’ to store their equipment for which a single locker suffices for each of them. So we now have 2 lockers that have been used and 1 unused locker which has free space for storage.

2.John needs to store his helmet at this point and no longer needs the old equipment that he stored before. Now ideally, he should be taking out the older equipment and putting his helmet in it’s place. But he asks for another locker from the manager and decides to put the helmet in the new locker. Logically, all the lockers are used up after this. Having been gifted with the memory of a warthog, John forgets about the equipment that he had stored in the first locker.

3.Danny needs to store 2 helmets now and needs 2 lockers, so he decides to remove his older equipment and frees up 1 locker. He now asks for an extra locker from the manager, but is refused since all the lockers have been used up.

Here, Danny would not be able to utilize the storage space that would have actually been available if John had removed the unused equipment from the locker.

2) Multiple instances of the same texture: A texture takes up width*height*4 (1 byte each for red, green, blue and alpha) of memory space. So an image of size 512×512 will take up 1.05 MB of memory. The same texture used 3 times would then take 3.15 MB of memory. So we would be using 3 times more memory if we used those many instances of the image as a texture.

Analogy: Consider a square sticker which shows your favourite character, ‘buttman ‘and can be reused for an infinite number of times.

You need to show this cool new character to 3 different people. So you can either:

1.Get 2 more stickers which are exactly the same, get 3 wooden frames on which you plan to stick the stickers and send the wooden frames to those 3 people.

2.Ask the 3 people to get their own wooden frames and just let them put the sticker on their wooden frames to see how it looks.

Case 2 works for us since we can just reuse the same sticker multiple times. It actually works in parallel in case of a software program, so all of them can look at buttman at the exact same time. Magic, yeah.

3) Unnecessary Iterations: Calling a for/while loop once is easier on the resources than calling it multiple times. Batch multiple tasks in one loop if you can.

Analogy: You are a spy assigned to deliver packages to 3 different, far off locations in tropical heat. You have also been asked to get top secret info by a different boss from the same 3 locations above.

Since both the tasks have been assigned to you by different bosses, you can either:

1.Group your mission according to the boss i.e. You would drive over to all 3 locations to complete the task given by Boss A first, then drive over again to the same 3 locations to complete the task given by Boss B. Or vice versa.

2.Group your mission according to the locations. i.e. You would drive to the first location, deliver the package and get information, then move on to the next location.

You would be a damn stupid spy if your mission plan was Case 1 due to the simple fact that it takes a longer time and more resources to complete the same set of tasks.

4) Keeping unused objects in memory: At any given point in time, only a definite number of objects will be used and / or shown on the screen. Since we have limitations on the memory that can be used, any additional objects still in memory are a drain on resources and should be released.

Analogy: You need to push a cart from point A to point B. Let’s assume that the task at hand would be easier if the load on the cart is non-existent or lighter at the very least. Since you love beer, you load up the cart with a barrel of beer anyway, which just makes the task at hand harder, you alcoholic nitwit.

So the best solution would be to not load up the barrel even if your emotions say otherwise.

The list of problems is definitely more than I could write about in a single article. As a developer, you should be able to identify these problems quickly and apply the needed solution. Shipping the product after overcoming these challenges is what makes game development exciting. Everyone has 24 hours in a day. For us, it’s the idea of other human beings spending and enjoying some of those precious hours of their lives on something that we create, that pushes us to develop games for the populace to consume. (source:gamecareerguide