博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
10、Libgdx的内存管理
阅读量:6094 次
发布时间:2019-06-20

本文共 2451 字,大约阅读时间需要 8 分钟。

(官网:)

游戏是非常耗资源的应用。图片和音效可能耗费大量的内存,另一方面来说,这些资源没有被Java垃圾回收,让一个垃圾处理来决定将显存中的5M的图片进行释放也不是一个明知的选择。

我们希望尽可能的在生命周期内管理好我们的资源。在Libgdx中有多个类来表示这些资源。它们都统一继承一Disposable接口,这个类对需要释放的资源进行管理。释放资源失败将会导致内存泄漏。

这些类需要手动进行释放(可能不完整):

  • AssetManager

  • Bitmap

  • BitmapFont

  • BitmapFontCache

  • CameraGroupStrategy

  • DecalBatch

  • ETC1Data

  • FrameBuffer

  • Mesh

  • Model

  • ModelBatch

  • ParticleEffect

  • Pixmap

  • PixmapPacker

  • Shader

  • ShaderProgram

  • Shape

  • Skin

  • SpriteBatch

  • SpriteCache

  • Stage

  • Texture

  • TextureAtlas

  • TileAtlas

  • TileMapRenderer

  • com.badlogic.gdx.physics.box2d.World

  • 所有的bullet类

资源文件要在不使用是尽快的释放,访问释放的资源将会导致错误。要确保这样的事情不要发生。

要判断一个特定的类是否需要释放,可以看一下它有没有disposed()方法,如果有,则需要释放。

对象轮询

对象轮询是重复利用未激活或者“死掉”的对象的基本原则,而不是每次都创建新的对象。可以通过创建一个对象池来完成,当你需要一个新的对象是,你可以从对象池中获取。如果池中有可用的对象,就返回,如果池是空的或者不包含可用的对象,将会创建一个新的对象的实例并返回。当你不需要一个对象时,需要进行释放,这就意味着将对象返回到池中。通过这种方式达到分配内存的重复利用。

这在游戏的内存管理中至关重要。

Libgdx提供了一系列的工具来实现简单的轮询。

  • Poolable接口

  • Pool

  • Pools

    继承Poolable接口意味着你需要在你的对象中有一个reset()方法。这个方法可以自动调用释放你的对象。

以下是一个简单的示例:

public class Bullet implements Poolable {public Vector2 position;public boolean alive;/** * 构造器,初始化. */public Bullet() {    this.position = new Vector2();    this.alive = false;}/** * 初始化,从对象池中获取 */public void init(float posX, float posY) {    position.set(posX,  posY);    alive = true;}/** * 回调方法 */@Overridepublic void reset() {    position.set(0,0);    alive = false;}/** *更新 */public void update (float delta) {    // 更新位置    position.add(1*delta*60, 1*delta*60);    // 屏幕之外,设置为dead    if (isOutOfScreen()) alive = false;}

}

在游戏的world类中:

public class World {// Bullet类private final Array
activeBullets = new Array
();// bullet池private final Pool
bulletPool = new Pool
() {@Overrideprotected Bullet newObject() { return new Bullet();}};public void update(float delta) { // 新的Bullet Bullet item = bulletPool.obtain(); item.init(2, 2); activeBullets.add(item); //释放bullet 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
bulletPool = Pools.get(Bullet.class);

怎样使用Pool

一个Pool<>管理一个单独类型的对象。从一个特定的Pool实例中取出,然后释放之后返回到Pool中。对象可能会实现Poolable接口,这将会在对象返回到Pool中自动进行重置。对象将按需分配。

你必须实现你自己的Pool<>子类,因为newObject方法是抽象的。

(版权所有,如需转载,注明出处)

转载于:https://www.cnblogs.com/hainange/p/6153489.html

你可能感兴趣的文章
Linux面试题
查看>>
! [rejected] master -> master (non-fast-forward)
查看>>
STL unique
查看>>
装饰自己的博客园界面
查看>>
django-返回客户端外网ip服务
查看>>
linux内核初始化控制流
查看>>
A Wasserstein Distance[贪心/模拟]
查看>>
推荐几个比较好的网站
查看>>
Project Euler 45 Triangular, pentagonal, and hexagonal( 二分 + 函数指针 )
查看>>
为什么成员属性不会被重写
查看>>
SQL Server, Cannot resolve the collation conflict
查看>>
VIM技巧:选择文本块
查看>>
10分钟了解JSON Web令牌(JWT)
查看>>
Python 函数
查看>>
java低级版的分页功能:只是备忘
查看>>
102422关系
查看>>
用户 'sa' 登录失败。该用户与可信 SQL Server 连接无关联'。错误代码:18452 解决办法...
查看>>
山寨小小军团开发笔记 之 Arrow Projectile
查看>>
周鸿祎:如何成为一名优秀的产品经理?
查看>>
项目使用Entity Framework用到的公共操作方法基类(Repository)及其使用 (转载)
查看>>