2012-12-05 27 views
6

Tôi có một trò chơi đang chạy, nhưng nó đã được nói lắp ngẫu nhiên. Điều này làm cho tôi nghĩ rằng GC đang chạy. Sau khi tra cứu mã, tôi thấy rất nhiều tin nhắn GC_CONCURRENT, như 4-5 giây.LibGdx GC_Con đang chạy

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 thu hẹp thủ phạm của tôi vào lớp hiển thị của tôi. Im chỉ học LibGdx (đây là ứng dụng LibGdx đầu tiên của tôi) và đã tự hỏi liệu có ai có thể thấy vấn đề không.

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(); 

} 

Tôi đã thử nhận xét khỏi các khối và có vẻ như tôi nhận được cuộc gọi GC ở mọi nơi, mặc dù nhiều hơn ở giữa.

CHỈNH SỬA: TRẢ LỜI

Sử dụng câu trả lời bên dưới Tôi đã sử dụng DDMS để xem phân bổ. Nó đã làm khoảng 100 đối tượng mới một giây ... float [], khu vực kết cấu, ma ... tất cả kết hợp với các

skin.getSprite("texture"); 

mỗi cuộc gọi được thực hiện một phao [], một khu vực kết cấu, và một sprite . Vì vậy, cảm ơn cho việc phân bổ DDMS nhìn lên. Giải pháp là những gì Yul nói bằng cách tạo các sprites (các trường) trong hàm constructor sau đó sử dụng gọi chúng trong hàng.

vì vậy đây ...

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

thay đổi này ...

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

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

Bây giờ không có nhiều cuộc gọi GC, và các trò chơi dường như bị chạy mượt mà hơn.

Cảm ơn

+0

Cố gắng thay thế các trình vòng lặp có lập chỉ mục trong vòng lặp. –

+1

Tôi nghĩ bạn nên chuyển 'skin.getSprite' đó thành' create'. Tạo sprite trong 'Create' và vẽ trong' onRender' –

Trả lời

3

Sử dụng công cụ Theo dõi phân bổ DDMS để theo dõi các vấn đề cụ thể. (Chạy ứng dụng trên thiết bị Android của bạn, mở cửa sổ DDMS, chuyển sang tab Theo dõi phân bổ, chọn quá trình của bạn trong tab "Thiết bị", tải trò chơi của bạn, nhấp "bắt đầu theo dõi", đợi vài giây, nhấp "nhận phân bổ ", nhìn vào bảng dữ liệu. Tôi tìm thấy phân loại trên threadId là một cách tốt đẹp để cô lập hoạt động thread render từ chủ đề nền khác.)

Iterators tạo đối tượng tạm thời, đặc biệt là trong một vòng lặp render, bạn nên sử dụng lập chỉ mục rõ ràng .

Ghép chuỗi cũng tạo đối tượng tạm thời.

Có lẽ có rất nhiều bộ nhớ địa điểm tinh tế khác đang được phân bổ, nhưng cách đúng để tìm ra điều này là sử dụng đúng công cụ.

+0

Sử dụng câu trả lời ở trên tôi đã sử dụng DDMS để xem phân bổ. Nó đã tạo ra khoảng 100 vật thể mới một giây ... float [], vùng kết cấu, sprite ... tất cả liên kết với – user835692