我目前正在使用 libgdx 框架开发一个小型桌面 java 游戏。一切都工作正常,除了一些非常奇怪的 CPU 使用行为。
当仅运行带有空渲染循环的框架后台时,我的 CPU 使用率约为 28%。考虑到 lbgdx 也在进行一些管理并且渲染方法被尽可能快地调用,这似乎很好。
但是事情开始变得疯狂......
当绘制和更新约 200 个对象时,CPU 使用率跃升至约 55%。然而 Libgdx 告诉我它只使用一个 open gl 绘制调用。那么 CPU 开销应该非常低,不是吗? CPU 使用率也不是由更新循环引起的。我已经尝试删除它,但使用率仍然高达 50% 左右。
但情况变得更糟......
我偶然发现,当程序需要处理大量对象(大约 50000 个)时,使用率会下降到 30% 左右。
如果我释放大量对象然后返回到 200 个对象,CPU 使用率会进一步下降到约 20%。
如果我重复这个过程,使用率最终会下降到 3%。是的,3%。 并将保持在 3%。 (只要我不分配任何其他对象。当然,使用量会增加)
总结一下:我正在渲染完全相同的场景。起初,CPU 使用率为 55%。在分配和释放大量对象后,CPU 使用率达到 3%。
这怎么可能发生?
起初我认为lidgdx正在使用批处理系统,它将创建批量的顶点、颜色信息和纹理坐标,以最大限度地减少绘制调用的数量。 如果我将批量大小设置为每批 2500 个 Sprite ,CPU 使用率将下降到 30% - 40%。然而,奇怪的分配和释放效果仍然发生。
如果有帮助的话,我还会向您提供我的更新、绘制、渲染和清除方法。
渲染方法:
@Override
public void render()
{
//the basic game loop components
//update all and draw everything
update();
draw();
//Entity.alive refers to an ArrayList containing
//all objects that'll be updated and draw in the
//render loop
System.out.println("ENTITY COUNT " + Entity.alive.size());
//and remove all the dead bodies
//from the carpet ... you know
//i can't stand blood ...
//and make some new ones, too
clear();
while((System.nanoTime() / 1000000) - time_last < 16)
{
//nothing to do here ... (imagine meme)
try
{
Thread.sleep(0, 1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
time_last = System.nanoTime() / 1000000;
}
更新方法:
public void update()
{
//update all the entities
//in the "alive" ArrayList
for(Entity e: Entity.alive) e.update();
//add all entities declared
//dead to the dead list
for(Entity e: Entity.alive)
{
//not dead - nothing to do here
if(e.getState() == true) continue;
//else add to dead list!
Entity.dead.add(e);
}
}
绘制方法:
public void draw()
{
//clear the screen
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
//update the view
Draw.updateCamera();
//start a batch section
//all further calls will
//be packed an sent to
//gpu in one flush
Draw.startBatch();
//draw all living entities
for(Entity e: Entity.alive) e.draw();
//draw all the level
//geometry and sprites
Level.draw();
//ending the sprite batch
Draw.endBatch();
}
清除方法:
public void clear()
{
//remove all dead objects
for(Entity e: Entity.dead)
{
Entity.alive.remove(e);
}
//clear the array of the dead
Entity.dead.clear();
//add all the newly created
//objects to the alive list
for(Entity e: Entity.born)
{
Entity.alive.add(e);
}
//clear the creation list
Entity.born.clear();
}
我正在使用 java 1.8.0_31-b13 在 eclipse 4.4.1 中开发程序。 操作系统为Windows 8.1。
最佳答案
你的 render() 方法有点奇怪。 我不知道这是否会导致疯狂的 cpu 计时,以下代码是不必要的,因为 LibGDX 本身会处理 16.6 毫秒的等待时间(对于 60Hz)。如果你的定时器与 LibGDX 定时器不匹配,可能会造成一些麻烦。因此,您可能会等待太长时间,从而显着降低 CPU 负载。删除实体时,计时器将不同步 -> 减少 CPU 使用率。
while((System.nanoTime() / 1000000) - time_last < 16)
{
//nothing to do here ... (imagine meme)
try
{
Thread.sleep(0, 1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
关于java - 使用 LibGdx 在 Java 中出现奇怪的 CPU 使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29307705/