第九章 Libgdx内存管理
Android游戏开发群:290051794
Libgdx游戏开发框架交流群:261954621
游戏是使用资源较多的应用。图像和音效会占用大量的内存。此外,这些资源大部分不是通过java的垃圾回收器管理,而是由本地驱动管理。使用垃圾回收器对纹理等进行回收不是一个明智的做法。
我们需要合理的控制资源的生命周期。在Libgdx中有多个类实现这个功能。它们都实现Disposable接口指明在生命周期结束后要销毁的类的实例。错误的释放资源会导致内存泄露。
下面的类需要手工处理:
AssetManager
Bitmap
BitmapFont
BitmapFontCache
CameraGroupStrategy
DecalBatch
ETC1Data
FrameBuffer
Mesh
ParticleEffect
Pixmap
PixmapPacker
ShaderProgram
Shape
Skin
SpriteBatch
SpriteCache
Stage
Texture
TextureAtlas
TileAtlas
TileMapRenderer
com.badlogic.gdx.physics.box2d.World
当资源不再使用应尽快的进行释放,释放与它们有关的内存。访问一个已经释放的资源会导致未定义错误,所以要处理所有资源的引用。
当你想知道一个类是不是需要释放,检查它是否有dispose()方法。如果有,那么你正在使用本地资源。
对象池
对象池是重新使用闲置的或“死掉”的对象,而不是每次都创建新的对象。这通过一个对象池实现,当你需要一个对象时,从对象池中获得。如果对象池有可用的对象,则返回。如果对象池是空的,或者没有闲置的对象,会创建一个对象的一个新的实例并返回。当你不再需要一个对象,并释放它。就意味着它返回到对象池。通过这种方式,对象分配的内存重新被使用。
对于需要生成大量对象,比如子弹,障碍,怪物等等,的游戏来说,这对内存管理是重要的。
Libgdx对简单池提供了一些工具:
Poolable interface
Pool
Pools
实现Poolable接口意味着你需要在对象中实现reset()方法,它会自动的释放你的对象。
下面是一个简单的例子:
public class Bullet implements Poolable { public Vector2 position; public boolean alive; /** * Bullet 构造函数,初始化变量。. */ public Bullet() { this.position = new Vector2(); this.alive = false; } /** * 初始化Bullet当从对象池中获取Bullet是调用。 */ public void init(float posX, float posY) { position.set(posX, posY); alive = true; } /** *对象空闲的回调方法,自动被 Pool.free()调用。 */ public void reset() { position.set(0,0); alive = false; } /** * 更新 */ public void update (float delta) { // update bullet position position.add(1*delta*60, 1*delta*60); // if bullet is out of screen, set it to dead if (isOutOfScreen()) alive = false; } }在游戏中:
public class World() { // array containing the active bullets. private final Array<Bullet> activeBullets = new Array<Bullet>(); // bullet pool. private final Pool<Bullet> bulletPool = new Pool<Bullet>() { @Override protected Bullet newObject() { return new Bullet(); } }; public void update(float delta) { // if you want to spawn a new bullet: Bullet item = bulletPool.obtain(); item.init(2, 2); activeBullets.add(item); // if you want to free dead bullets, returning them to the pool: Bullet item; int len = activeBullets.size; for (int i = len; --i >= 0;) { item = activeBullets.get(i); if (item.alive == false) { activeBullets.removeIndex(i); bulletPool.free(item); } } } }
Pools类提供了动态创建任何对象池的静态方法。在上面的示例中,可以这样使用:
private final Pool<Bullet> bulletPool = Pools.get(Bullet.class);
作者:宋志辉
出处:http://blog.csdn.net/song19891121
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
支持: 新浪微博 腾讯微博