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

时间: 2024-09-13 02:05:08

第九章 Libgdx内存管理的相关文章

《DB2性能管理与实战》——第2章 DB2内存管理

第2章 DB2内存管理 DB2性能管理与实战数据库的性能管理受系统中的可用资源量.充分利用和共享可用资源的程度等因素的影响.理解DB2如何使用内存,可以优化内存的使用,防止过度分配内存或者内存分配不足,从而获得更好的性能并且避免资源的浪费.本章将介绍DB2的内存工作原理和进行内存管理的要点,使读者能够对DB2的内存模型有一个清晰的认识,为理解后续章节中的优化工作做准备. 本文仅用于学习和交流目的,不代表异步社区观点.非商业转载请注明作译者.出处,并保留本文的原始链接.

高质量C++/C编程指南-第7章-内存管理(1)

欢迎进入内存这片雷区.伟大的Bill Gates 曾经失言: 640K ought to be enough for everybody - Bill Gates 1981 程序员们经常编写内存管理程序,往往提心吊胆.如果不想触雷,唯一的解决办法就是发现所有潜伏的地雷并且排除它们,躲是躲不了的.本章的内容比一般教科书的要深入得多,读者需细心阅读,做到真正地通晓内存管理. 7.1内存分配方式内存分配方式有三种: (1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行

10、Libgdx的内存管理

(官网:www.libgdx.cn) 游戏是非常耗资源的应用.图片和音效可能耗费大量的内存,另一方面来说,这些资源没有被Java垃圾回收,让一个垃圾处理来决定将显存中的5M的图片进行释放也不是一个明知的选择. 我们希望尽可能的在生命周期内管理好我们的资源.在Libgdx中有多个类来表示这些资源.它们都统一继承一Disposable接口,这个类对需要释放的资源进行管理.释放资源失败将会导致内存泄漏. 这些类需要手动进行释放(可能不完整): AssetManager Bitmap BitmapFon

高质量C++/C编程指南-第7章-内存管理(7)

7.11 new/delete 的使用要点运算符new使用起来要比函数malloc简单得多,例如: int *p1 = (int *)malloc(sizeof(int) * length); int *p2 = new int[length]; 这是因为new内置了sizeof.类型转换和类型安全检查功能.对于非内部数据类型的对象而言,new在创建动态对象的同时完成了初始化工作.如果对象有多个构造函数,那么new的语句也可以有多种形式.例如 class Obj { public : Obj(v

高质量C++/C编程指南-第7章-内存管理(4)

7.5 free和delete把指针怎么啦?7.7 杜绝"野指针""野指针"不是NULL指针,是指向"垃圾"内存的指针.人们一般不会错用NULL指针,因为用if语句很容易判断.但是"野指针"是很危险的,if语句对它不起作用. "野指针"的成因主要有两种: (1)指针变量没有被初始化.任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气.所以,指针变量在创建的同时应当被初始化,要么

Android群英传笔记——第九章:Android系统信息和安全机制

Android群英传笔记--第九章:Android系统信息和安全机制 本书也正式的进入尾声了,在android的世界了,不同的软件,硬件信息就像一个国家的经济水平,军事水平,不同的配置参数,代表着一个android帝国的强弱,所以厂商喜欢打配置战,本节就要是讲 Android系统信息的获取 PackageManager的使用 ActivityManager的使用 Android安全机制 一. Android系统信息的获取 由于android手机的开源性,手机的配置各种各样,那些优化大师之类的东西

第四章、存储器管理

第四章.存储器管理 物理地址和逻辑地址 物理地址:存储单元的编号,可以直接寻址. 逻辑地址:程序中的地址,是可以改变的,不可直接寻址. 重定位:将逻辑地址空间的逻辑地址变换成内存空间的物理地址的过程. 静态重定位和动态重定位 静态重定位:当用于程序被装入内存时,一次性地实现逻辑地址到物理地址的转换,以后不再转换(一般在装入内存时由软件完成),直到该程序完成退出内存为止. 动态重定位:当用户程序被装入内存时,并不将其逻辑地址转换,而是保留原来的逻辑地址.等程序真正要执行时才将其逻辑地址通过动态计算

第九章 方法[《.net框架程序设计》读书笔记]

.net框架|笔记|程序|设计 第九章 方法 一. 实例构造器 1. 前面提到用new操作符创建对象时的三部曲: l 为对象分配内存 l 初始化对象的附加成员(方法表指针和SyncBlockIndex) l 调用实例构造器初始化实例状态 在分配内存时,系统将所有内存位置均置为0值,这就是为什么字段初始化而未赋值时均为0或null值. 不调用实例构造器的情况: l 调用Object.MemberwiseClone()方法创建实例(分配内存:初始化附加成员:将源对象字节拷贝到新创建的对象) l 反序

JVM内存管理:GC算法精解---分代搜集算法

引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法,而且几乎是一定会有,因为LZ相信高人们的能力. 那么分代搜集算法是怎么处理GC的呢? 对象分类 上一章已经说过,分代搜集算法是针对对象的不同特性,而使用适合的算法,这里面并没有实际上的新算法产生.与其说分代搜集算法是第四个算法,不如说它是对前三个算法的实际应用. 首先我们来探讨一下对象的不同特性,接下来LZ和各位来一起给这些对象选择GC算法. 内存中的对象按照生命周期的长短大致可以分为三种