Libgdx中Batch.draw引发堆内存增长问题排查求助
问题根源:SpriteBatch的
begin()和end()未配对调用 你遇到的内存持续增长问题,核心原因是你的render()方法里只调用了batch.begin(),却没有对应的batch.end()——这是LibGDX SpriteBatch使用的典型错误。
为什么会导致内存泄漏?
SpriteBatch的工作逻辑依赖begin()和end()的配对调用:
- 调用
begin()时,它会初始化内部顶点缓冲区、设置渲染状态; - 每次
draw()都会把精灵的顶点、纹理坐标等数据写入这个缓冲区; - 只有调用
end(),才会把缓冲区的数据提交给GPU渲染,同时重置内部状态、清理临时占用的内存。
如果只调用begin()不调用end():
- 每次
render()循环触发时,SpriteBatch会检测到上一次的begin()未结束,可能会创建新的临时缓冲区或不断扩容现有缓冲区; - 你的
for循环每次draw()都在往缓冲区里追加数据,这些数据永远不会被提交到GPU,只会在堆内存里持续累积,也就是你看到的每3秒增长3MB; - 当缓冲区占用的堆内存达到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
相关产品推荐
相关产品推荐

