java - 使用 LibGdx 在 Java 中出现奇怪的 CPU 使用率

标签 java opengl libgdx cpu-usage

我目前正在使用 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/

相关文章:

java - 从 Maven 存储库部署到 destr 服务器

java - 如何在 for 循环中使用 getIndices ?

java - 从大文件中选择什么来读取?

java - 我如何在这些坐标处添加 3d 立方体? OpenGL11

java - 如何更改 LibGdx 中相机的位置?

java - ArrayList Integer - 在不考虑极值的情况下计算平均成绩

opengl - GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 始终返回 0

c++ - 四元数旋转不起作用

java - Libgdx 播放器旋转困惑

java - 如何获取android assets的绝对路径