2012-07-05 161 views
0

我正在開發一款Android遊戲。隨着遊戲的進展,它變得越來越慢。我相信一些速度變化是由於敵人數量較高等原因造成的,但我也擔心我可能會發生內存泄漏。Android內存泄漏ArrayList

遊戲的本質是這樣的:

它與列表和數組建一個塔防遊戲。所有的塔式數據都存儲在衆多的遊戲板數組中。在整個繪圖和更新代碼中,評估每個塊。大多數時候都不需要做任何事情。遊戲是一個30x14的網格,因此在整個循環過程中可能會評估420個位置。這不是偉大的編程,但我認爲代碼很簡單,它可以正常工作。大多數時候都不需要做任何事情,所以我不認爲這很重要。

敵人,所有的子彈和各種粒子效果都存儲和更新等下方觀察的代碼列表。我幾天前剝皮了遊戲,保持所有遊戲邏輯相同,但添加了效果。添加位圖和着色風格不會改變遊戲的運行方式。當我添加如下所示的粒子效應時,放緩很明顯。他們不會在比賽早期造成任何放緩。後來在遊戲中他們做到了。因爲這個,我認爲內存管理錯了。

我有這樣一羣不同的類:

public class FadeBlock { 
    private float x; 
    private float y; 
    private float radius; 
    private int level; 
    private float startRadius; 
    private float endRadius; 
    private float elapsedTime; 
    private float fadeTime; 
    private boolean terminate; 
    private float percent; 

    public FadeBlock(int Level, float CenterX, float CenterY, float StartRadius, float EndRadius, float FadeTime) 
    { 
     x = CenterX; 
     y = CenterY; 
     level = Level; 
     fadeTime = FadeTime; 
     terminate = false; 
     percent = 1; 
     startRadius = StartRadius; 
     endRadius = EndRadius; 
     radius = startRadius; 
    } 

    public void Update(float ElapsedTime) 
    { 
     elapsedTime += ElapsedTime; 
     percent = (((float) elapsedTime)/((float)fadeTime)); 
     radius = (endRadius - startRadius)*percent + startRadius; 

     if (percent >= 1) 
     { 
      terminate = true; 
     } 
    } 

    public void Draw(Canvas canvas, Paint paint) 
    { 
     if (!terminate) 
     { 
      switch (level) { 
      case 1: 
       paint.setARGB(255, 61, 190, 255); 
       break; 
      case 2: 
       paint.setARGB(255, 162, 0, 194); 
       break; 
      case 3: 
       paint.setARGB(255, 0, 194, 162); 
       break; 
      case 4: 
       paint.setARGB(255, 129, 194, 0); 
       break; 
      case 5: 
       paint.setARGB(255, 255, 85, 0); 
       break; 
      case 6: 
       paint.setARGB(255, 194, 65, 0); 
       break; 
      default: 
       paint.setARGB(255, 61, 190, 255); 
       break; 
      } 
      paint.setAlpha((int) (255*(1 - percent))); 

      canvas.drawRect(x-radius, y - radius, x + radius, y + radius, paint); 
     } 
    } 

    public boolean Kill() 
    { 
     return terminate; 
    } 

} 

那我添加到一個ArrayList是這樣的:

public List<FadeBlock> FadingBlocks = new ArrayList<FadeBlock>(); 

和管理與下面的循環:

for (int i = 0; i < FadingBlocks.size(); i++) 
{ 
    FadingBlocks.get(i).Draw(canvas, paint); 
} 

for (int i = 0; i < FadingBlocks.size(); i++) 
{ 
    FadingBlocks.get(i).Update(elapsedTime); 
} 

for (int i = (FadingBlocks.size() - 1); i > -1 ; i--) 
{ 
    if (FadingBlocks.get(i).Kill()) 
{      
     FadingBlocks.remove(i); 
    } 
} 

將項目添加到列表中我做這樣的事情:

FadeBlock tempBlock = new FadeBlock(Units.get(i).getLevel(), Units.get(i).getX()+16, Units.get(i).getY()+16, 16, 32, 250)     
FadingBlocks.add(tempBlock); 

那是一個糟糕的方式來管理我的對象?這會導致android設備上的內存問題?

+1

不要擔心,你可能有內存泄漏。使用工具,並確保你做(或不)。有很多工具可以用來檢查內存泄漏。實際上,開始的一個好地方是查看本頁右欄中列出的一些帖子。 – 2012-07-05 15:09:58

+0

使用內存分析器。不要猜測。 – 2012-07-05 15:12:23

+0

我一直在使用DDMS。 LogCat中沒有顯示內存問題,我不知道如何使用其他工具來充分利用它們。這只是令人困惑,爲什麼我的遊戲會放緩。屏幕上並沒有更多的東西被吸引,而敵人在後來的水平上做的不多。 – 2012-07-05 15:17:34

回答

3

這是真實的很難知道這樣或那樣從幾行代碼導致內存泄漏。這裏有一個想法給你:

使用ObjectPool模式爲您的遊戲:你創建n個敵人,同時啓動你的遊戲,他們中的一些無效。然後當你需要一個新的敵人,而不是創建一個新的並將其添加到你的ArrayList,你從一個非活動的池中取出一個,並激活它。同樣,不是刪除一個敵人,而是將其標記爲在池中不活動。

這可以防止內存過度使用,作爲一個ArrayList與x的容量開始,需要將提高到2倍等時......但是當你刪除的對象永遠不會釋放內存。還將對象池存儲在靜態列表中而不是數組列表中,因爲迭代和訪問對象的速度會更快。

+0

這是個好主意。我認爲這將有助於解決您可能遇到的幾個問題。 – 2012-07-05 15:28:42