10、Libgdx的内存管理

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

(官网:www.libgdx.cn

游戏是非常耗资源的应用。图片和音效可能耗费大量的内存,另一方面来说,这些资源没有被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;
}
/**
 * 回调方法
 */
@Override
public 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<Bullet> activeBullets = new Array<Bullet>();
// bullet池
private final Pool<Bullet> bulletPool = new Pool<Bullet>() {
@Override
protected 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<Bullet> bulletPool = Pools.get(Bullet.class);

怎样使用Pool

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

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

www.libgdx.cn版权所有,如需转载,注明出处)

目录
相关文章
|
10天前
|
监控 Java Android开发
深入探讨Android系统的内存管理机制
本文将深入分析Android系统的内存管理机制,包括其内存分配、回收策略以及常见的内存泄漏问题。通过对这些方面的详细讨论,读者可以更好地理解Android系统如何高效地管理内存资源,从而提高应用程序的性能和稳定性。
40 16
|
5月前
|
存储 缓存 Java
Android性能优化:内存管理与LeakCanary技术详解
【7月更文挑战第21天】内存管理是Android性能优化的关键部分,而LeakCanary则是进行内存泄漏检测和修复的强大工具。
|
4月前
|
存储 Java 图形学
UNITY性能优化☀️一、GC介绍与Unity内存管理方法
UNITY性能优化☀️一、GC介绍与Unity内存管理方法
|
存储 消息中间件 API
FreeRTOS入门教程(堆和栈)
FreeRTOS入门教程(堆和栈)
344 0
|
存储 算法 Java
iOS开发 - 穿针引线之内存管理(二)
iOS开发 - 穿针引线之内存管理
227 0
|
存储 程序员 C语言
iOS开发 - 穿针引线之内存管理(一)
iOS开发 - 穿针引线之内存管理
188 0
|
iOS开发
iOS-底层原理 33:内存管理(二)强引用分析
iOS-底层原理 33:内存管理(二)强引用分析
197 0
iOS-底层原理 33:内存管理(二)强引用分析
|
Java 编译器 Swift
iOS开发篇-内存管理(中)
现在iOS开发已经是ARC甚至是swift的时代,但是内存管理仍是一个重点关注的问题,如果只知盲目开发而不知个中原理,踩坑就跳不出来了,理解好内存管理,能让我们写出更有质量的代码。
|
Swift iOS开发
iOS开发篇-内存管理(上)
现在iOS开发已经是ARC甚至是swift的时代,但是内存管理仍是一个重点关注的问题,如果只知盲目开发而不知个中原理,踩坑就跳不出来了,理解好内存管理,能让我们写出更有质量的代码。
|
编译器 Swift iOS开发
iOS开发篇-内存管理(下)
现在iOS开发已经是ARC甚至是swift的时代,但是内存管理仍是一个重点关注的问题,如果只知盲目开发而不知个中原理,踩坑就跳不出来了,理解好内存管理,能让我们写出更有质量的代码。