Libgdx内存管理和对象池

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2014/05/11/libgdx-memory-pool-manage/

Libgdx是跨平台的,而一般为了开发方便我们是在PC端调试,同时周期性地在Android平台测试。

通常而言,PC端的性能远高于Android平台,特别是对于模拟器而言,所以内存和效率开销是一个需要重点注意的问题。

游戏也是一种重资源应用。图片、音效、动画等等都会占用相当客观的内存,但同时它们又是被JAVA的GC所管理的,而有时候这不是很好的选择。

可以手动释放的资源

Libgdx中定义了Disposable接口,实现了该接口的所有类都可以在生命周期结束时手动控制。

以BitmapFont为例,它使用Batch进行绘制,而所有文字都缓存于BitmapFontCache中。那么在声明周期结束时需要手动释放掉它所用的资源。

publicvoiddispose () {
if (ownsTexture) {
for (int i =0; i < regions.length; i++)
regions[i].getTexture().dispose();
}
}

其他常用的实现了Disposable接口的类有

  • AssetManager
  • Bitmap
  • BitmapFont
  • BitmapFontCache
  • DecalBatch
  • ETC1Data
  • Mesh
  • FrameBuffer
  • Pixmap
  • PixmapPacker
  • ShaderProgram
  • Skin
  • Texture
  • Stage
  • TextureAtlas
  • TileMapRenderer

最佳的释放时机

当资源不再时候之后你就可以考虑释放它们了,而当dispose()被调用后对资源的方法就会产生null错误,所以释放之前确保不再有任何使用。

当使用资源时,检查它是否有dispose()方法,如果有,那么它就是一个本地资源,需要手动控制。

对象池

对象池是一种重用“死去”的对象的方法,避免不断实例化新的对象。

有了对象池,在创建对象的时候就可以先检查池是否有可用的对象,如果有就返回;反之,就新建。

当不再使用这个对象,它将“死去”并返回池。

对象池一般应用在需要大量创建经常使用的对象,比如金币、障碍物、子弹、小怪兽等等。

对象池包含的对象需要实现Poolable接口,即一个reset()方法。使用它让对象“死去”。

以金币为例:

publicclass Coin implements Poolable {
private Vector2 position;
privateint value;

publicCoin (){
this.position =new Vector2();
this.value =1;
}

publicvoidinit(float posX,float posY,int value){
this.postion.set(posX,posY);
this.value = value;
}

publicvoidreset() {
position.set(0,0);
value =1;
}
}

在需要使用对象的地方

publicclass Valley {
privatefinal Pool<Coin> coinPool =new Pool<Bullet>(){
@Override
protected BulletnewObject() {
returnnew Coin();
}
}
}

当然你也可以使用ReflectionPool,它使用反射直接创建新的对象

privatefinal Pool<Coin> coinPool = Pools.get(Coin.class);

参考资料

Disposable

Memory management

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2014/05/11/libgdx-memory-pool-manage/

发表评论