第九章 Libgdx内存管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/song19891121/article/details/8981943

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
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 
支持: 新浪微博 腾讯微博
 

没有更多推荐了,返回首页