You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Libgdx中Batch.draw引发堆内存增长问题排查求助

问题根源:SpriteBatch的begin()和end()未配对调用

你遇到的内存持续增长问题,核心原因是你的render()方法里只调用了batch.begin(),却没有对应的batch.end()——这是LibGDX SpriteBatch使用的典型错误。

为什么会导致内存泄漏?

SpriteBatch的工作逻辑依赖begin()和end()的配对调用:

  • 调用begin()时,它会初始化内部顶点缓冲区、设置渲染状态;
  • 每次draw()都会把精灵的顶点、纹理坐标等数据写入这个缓冲区;
  • 只有调用end(),才会把缓冲区的数据提交给GPU渲染,同时重置内部状态、清理临时占用的内存。

如果只调用begin()不调用end():

  1. 每次render()循环触发时,SpriteBatch会检测到上一次的begin()未结束,可能会创建新的临时缓冲区或不断扩容现有缓冲区;
  2. 你的for循环每次draw()都在往缓冲区里追加数据,这些数据永远不会被提交到GPU,只会在堆内存里持续累积,也就是你看到的每3秒增长3MB;
  3. 当缓冲区占用的堆内存达到GC阈值时,就会触发垃圾回收,对应你观察到的每3分钟一次GC。

而移除batch.draw()后,虽然还是没有end(),但没有数据写入缓冲区,自然不会有内存累积,堆内存也就停止增长了。

修复方案

只需要在for循环结束后添加batch.end()即可:

public void render() { 
    camera.update(); 
    Gdx.gl.glClearColor(0.5f, 0.2f, 0, 1); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
    batch.begin(); 
    batch.setProjectionMatrix(camera.combined); 
    batch.setColor(1f, 1f, 1f, 1); 
    for( int y = 0 ; y < l1BlockedNd.size ; y++){ 
        batch.draw(pmxTexture[0], l1BlockedNd.get(y).getPosX() * 10, l1BlockedNd.get(y).getPosY() * 10); 
    } 
    // 必须添加这行,完成渲染流程并清理内存
    batch.end(); 
}

额外注意事项

  • 确保batch是全局唯一实例,不要在render()里每次创建新的SpriteBatch;
  • 如果后续仍有内存问题,可以用LibGDX自带的MemoryUtils工具进一步排查,但当前begin()/end()未配对是最直接的诱因。

内容的提问来源于stack exchange,提问作者Mycotina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:34:13