2012-12-05 14 views
6

Mam grę uruchomioną, ale zostało jąkanie losowo. To sprawia, że ​​myślę, że GC jest uruchomiony. Po wyszukaniu kodu widzę wiele wiadomości GC_CONCURRENT, np. 4-5 na sekundę.LibGdx GC_Concurrent running

12-04 22:14:22.018: D/dalvikvm(4757): GC_CONCURRENT freed 510K, 7% free 10139K/10823K, paused 4ms+6ms 
12-04 22:14:22.288: D/dalvikvm(4757): GC_CONCURRENT freed 497K, 7% free 10139K/10823K, paused 3ms+7ms 
12-04 22:14:22.558: D/dalvikvm(4757): GC_CONCURRENT freed 497K, 7% free 10139K/10823K, paused 3ms+6ms 
12-04 22:14:22.823: D/dalvikvm(4757): GC_CONCURRENT freed 497K, 7% free 10139K/10823K, paused 3ms+7ms 

Ive zawęziła mojego winowajcę do mojej klasy renderowania. Właśnie uczę się LibGdx (jest to moja pierwsza aplikacja LibGdx) i zastanawiałem się, czy ktoś może zobaczyć problem.

public void render(){ 

    batch.begin(); 

    //Draw background 
    batch.draw(skin.getSprite("background_chapter"), 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT); 

    //draw tiles 
    bIter = world.getBlocks().iterator(); 
    while(bIter.hasNext()){ 
     tile = bIter.next(); 

     switch(tile.getType()){ 
     case Values.ICE: 
      continue; 
     (many more cases...) 
     } 
     batch.draw(skin.getSprite(tr), tile.getPosition().x*scaleX, tile.getPosition().y*scaleY, tile.getBounds().width*scaleX, tile.getBounds().height*scaleY); 
    } 

    //put ice on top of other level elements, non mobile ice on bottom 
    bIter = world.getBlocks().iterator(); 
    while(bIter.hasNext()){ 
     tile = bIter.next(); 
     if(tile.getType() == Values.ICE && tile.getCollide() == false){ 
     batch.draw(skin.getSprite("ice"), tile.getPosition().x*scaleX, tile.getPosition().y*scaleY, tile.getBounds().width*scaleX, tile.getBounds().height*scaleY); 
     } 
    } 

      //mobile ice on top 
    bIter = world.getBlocks().iterator(); 
    while(bIter.hasNext()){ 
     tile = bIter.next(); 
     if(tile.getType() == Values.ICE && tile.getCollide() == true){ 
      batch.draw(skin.getSprite("ice"), tile.getPosition().x*scaleX, tile.getPosition().y*scaleY, tile.getBounds().width*scaleX, tile.getBounds().height*scaleY); 
     } 
    } 

    //pauly on top 
    batch.draw(skin.getSprite("pauly_moving"), pauly.getBounds().x*scaleX, pauly.getBounds().y*scaleY, pauly.getBounds().width*scaleX, pauly.getBounds().height*scaleY); 

    batch.draw(skin.getSprite("background_chapter"), 0+(SIDE_EDGE*scaleX), (9.6f*scaleY), CAMERA_WIDTH, 1*scaleY); 


    //draw UI elements 
    batch.draw(skin.getSprite("pause_menu_icon"), CAMERA_WIDTH-(SIDE_EDGE*scaleX), CAMERA_HEIGHT-(0.25f*scaleY), 1*scaleX, 1*scaleY); 
    batch.draw(skin.getSprite("restart_menu_icon"), SIDE_EDGE*scaleX, CAMERA_HEIGHT-(0.25f*scaleY), 1*scaleX, 1*scaleY); 

    font.draw(batch, "Moves: "+pauly.getCurrentMoves()+"/ "+world.getLevel().getMovesNeeded(), 2f*scaleX,10.1f*scaleY); 

    font.draw(batch, world.getLevel().getTitle(), 6f*scaleX,10.1f*scaleY); 
    //draws the FPS on screen 
    font.draw(batch, "FPS: "+(Gdx.graphics.getFramesPerSecond()), 12f*scaleX,10.1f*scaleY); 

    if(world.getState()==Values.PAUSED){ 
     batch.draw(skin.getSprite("pause_menu"), 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT); 
     //Gdx.app.log("WorldRenderer", "Game Paused"); 
    } else if(world.getState()==Values.LOOSE){ 
     batch.draw(skin.getSprite("die_menu"), 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT); 
     //Gdx.app.log("WorldRenderer", "Game Paused"); 
    } else if(world.getState()==Values.WIN){ 
     batch.draw(skin.getSprite("win_menu"), 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT); 
     //Gdx.app.log("WorldRenderer", "Game Paused"); 
    } 

    batch.end(); 

} 

Ive próbował wyłączyć komentowanie bloków i wydaje się uzyskać połączenia GC wszędzie, choć bardziej w środku.

EDIT: Odpowiedź

Korzystanie odpowiedź poniżej użyłem DDMS zobaczyć alokacji. To robił około 100 nowych obiektów na sekundę ... pływaka [], tekstury region, sprite ... wszystko związane z

skin.getSprite("texture"); 

każde wywołanie robił pływaka [], obszar tekstury i sprite . Dzięki za sprawdzenie przydziału DDMS. Rozwiązaniem było to, co powiedział Yul, tworząc spity (pola) w funkcji konstruktora, a następnie użyj wywoływania ich w linii.

więc ...

batch.draw(skin.getSprite("background_chapter"), 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT); 

zmieniony na ten ...

//in constructor() 
background = skin.getSprite("background_chapter"); 

//in render() 
batch.draw(background, 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT); 

już nie ma połączenia GC, a gra wydaje się działać płynniej.

Dzięki

+0

Spróbuj zastąpić iteratory indeksowaniem w pętli for. –

+1

Myślę, że powinieneś przenieść te 'skin.getSprite' do' create'. Utwórz sprite w 'Utwórz' i narysuj' onRender' –

Odpowiedz

3

pomocą narzędzia Alokacja Tracker DDMS wyśledzić gdzie konkretne problemy. (Uruchom aplikację na urządzeniu z Androidem, otwórz okno DDMS, przejdź do zakładki Tracker alokacji, wybierz proces na karcie "Urządzenia", uruchom grę, kliknij "rozpocznij śledzenie", poczekaj kilka sekund, kliknij "pobierz alokacje ", spójrz na tabelę danych, które znajduję na threadId jest dobrym sposobem na wyodrębnienie aktywności renderowania wątków z innych wątków tła.)

Iteratory tworzą obiekty tymczasowe, więc szczególnie w pętli renderowania powinieneś używać indeksowania jawnego .

Łączenie ciągów tworzy również obiekty tymczasowe.

Prawdopodobnie istnieje kilka innych, subtelnych miejsc, w których pamięć jest przydzielana, ale właściwym sposobem, aby to zrozumieć, jest użycie odpowiednich narzędzi.

+0

Używając powyższych odpowiedzi użyłem DDMS, aby zobaczyć alokację. Zrobiło około 100 nowych obiektów na sekundę ... float [], region tekstury, sprite ... wszystkie związane z – user835692