I have a game, but it stutters at random. It makes me think that the GC is working. After looking at the code, I see many GC_CONCURRENT messages, for example 4-5 seconds.
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 narrowed down my culprit in my rendering class. I am just learning LibGdx (this is my first LibGdx application) and was wondering if anyone could see the 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 tried commenting on blocks, and it seems like I get GC calls everywhere, although more in the middle.
EDIT: ANSWER
Using the answers below, I used DDMS to see the selection. He created about 100 new objects per second ... float [], texture area, sprite ... all related
skin.getSprite("texture");
each call made float [], texture area and sprite. So thanks for distributing DDMS. The solution was what Yul said, creating sprites (fields) in the constructor function, then using them in a line.
so that...
batch.draw(skin.getSprite("background_chapter"), 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT);
changed to this ...
//in constructor() background = skin.getSprite("background_chapter"); //in render() batch.draw(background, 0+(SIDE_EDGE*scaleX), 0+(BOTTOM_EDGE*scaleY), CAMERA_WIDTH, CAMERA_HEIGHT);
Now there are no more GC calls, and the game seems smoother.
thanks