Я тестировал свою почти законченную игру (созданную с помощью libgdx) для сбора мусора. Я запустил версию своего настольного компьютера с подробным gc и только двумя вариантами кучи VM.сборщик мусора вызывает во время рендеринга простой экран (libgdx)
Я был обеспокоен тем, что gc пинает каждый раз во время рендеринга экрана.
Я решил создать простой экран с одним этапом и добавить к нему одного актера изображения. Никаких других объектов не создано. Я заметил, что даже при такой простой настройке gc пинает каждый раз в то время.
С кодом ниже я получаю два ГЦ вызовов после запуска в течение около 5 минут:
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
public class TestScreen implements Screen {
private static final float viewportWidth = 40f;
private static final float viewportHeight = 24f;
private final Assets assets = new Assets();
private Stage stage;
@Override
public void render(float delta) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
@Override
public void resize(int width, int height) {
}
@Override
public void show() {
stage = new Stage(viewportWidth, viewportHeight, false);
Image image = new Image(assets.getMenuSkin(), "stars");
image.setSize(viewportWidth, viewportHeight);
image.setPosition(0f, 0f);
stage.addActor(image);
}
@Override
public void hide() {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void dispose() {
assets.dispose();
stage.dispose();
}
}
Вот результат:
[GC [DefNew: 998K->4K(1024K), 0.0014329 secs] 2336K->1359K(3124K), 0.0015340 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [DefNew: 964K->3K(1024K), 0.0005355 secs] 2319K->1358K(3124K), 0.0006174 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
И резюме:
Heap
def new generation total 1024K, used 133K [0x323c0000, 0x324d0000, 0x325c0000)
eden space 960K, 13% used [0x323c0000, 0x323e0918, 0x324b0000)
from space 64K, 5% used [0x324c0000, 0x324c0d10, 0x324d0000)
to space 64K, 0% used [0x324b0000, 0x324b0000, 0x324c0000)
tenured generation total 2100K, used 1355K [0x325c0000, 0x327cd000, 0x329c0000)
the space 2100K, 64% used [0x325c0000, 0x32712c48, 0x32712e00, 0x327cd000)
compacting perm gen total 12288K, used 2520K [0x329c0000, 0x335c0000, 0x369c0000)
the space 12288K, 20% used [0x329c0000, 0x32c36140, 0x32c36200, 0x335c0000)
ro space 10240K, 54% used [0x369c0000, 0x36f3daf0, 0x36f3dc00, 0x373c0000)
rw space 12288K, 55% used [0x373c0000, 0x37a61ce8, 0x37a61e00, 0x37fc0000)
Это данные OpenGL передаются по массивам, которые собирают мусор?
Из того, что я читал в книге Марио (начиная с Android-игр), я полагаю, что это не так. Насколько я помню, Марио написал об ошибке, которая заставила gc работать в этом случае, но она существовала только в ранних версиях Android.
Или, может быть, на настольных реализациях запускает gc и Android?
Зная немного о библиотеке openGL, которую вы используете, я задаюсь вопросом, как часто вызывается show()? Он создает новое изображение каждый раз и может засорять кучу слишком большим количеством объектов, заставляя GC сильно ударить. – arynaq
show() вызывается только один раз, когда экран должен отображаться. Я, как правило, ставил всю логику создания, потому что когда-то создавал материал libgdx в конструкторе класса, я использовал некоторую ошибку, не инициализированную контекстом. – Dzik