【问题标题】:Quickly unload bitmaps from memory从内存中快速卸载位图
【发布时间】:2012-12-19 23:44:20
【问题描述】:

我正在用 Java 创建这个 Android 游戏。我有很多图像,但不需要一次全部使用它们,所以我创建了一个资源管理器类来处理正在使用的位图。但是,我发现从内存中清除位图非常慢。我目前正在做这样的事情:

bitmap.recycle()
bitmap = null

System.gc (also tried Runtime.getRuntime().gc())

首先,有什么方法可以更快地从内存中卸载位图,或者是否有可能以某种方式检查它们是否真的被清除,以便我可以让加载屏幕也依赖于此?

【问题讨论】:

  • 您可能会考虑使用现有的位图缓存引擎而不是自己滚动:senab.co.uk/2012/12/18/android-bitmapcache-the-rebirth
  • 速度慢的原因是你正在调用 gc。让它在需要时运行。 +1 @CommonsWare 无需重新发明轮子。
  • 调用 .recycle() 并将其设置为 null 实际上应该这样做。无需调用 .gc() :)
  • @RasmusAppelkvist - 如果即将耗尽内存,JVM 将积极运行垃圾收集。你的责任以确保对象可以被垃圾回收结束。
  • 对此,我要补充一点,每次调用 System.GC 都会进行一次完整的垃圾回收;即使没有什么可收集的,这将是一个缓慢的操作。将其留给 Android 系统通常是一个更好的主意;这可能会选择频率和 - 最重要的 - 以比每次释放位图时简单地调用完整 GC 更好的方式执行的 GC 类型。

标签: java android bitmap


【解决方案1】:

当我们尝试System.gc() 时,不能保证垃圾收集器会真正运行,因为 gc() 需要某些先决条件,例如资源饥饿。所以很明显,调用 gc() 只是在浪费关键的 CPU 周期。作为开发人员,我们可以通过使引用无效来为 gc 收集不必要的对象。

在创建游戏系统(游戏)时,有几种优化技术可能会有所帮助。

  1. 使用纹理。这是example

  2. 使用 Sprite 和 SpriteSheets(与加载单个位图相比,它给系统带来的开销更少)。许多开源游戏引擎都在使用它。如果您不想使用它们,请了解如何从这些来源从头开始创建。

  3. 使用这些标准的 android 文档了解如何Loading Large Bitmaps EfficientlyCaching Bitmaps 以更好地使用位图。这个想法是,当用户的设备效率不足以处理处理量和/或游戏的内存较少时,您始终可以缩小位图(为了更好的响应而牺牲质量)。

  4. 始终针对内存泄漏问题测试您的应用。这是一个nice post,会有所帮助。

  5. 将在游戏内多次使用的物品保留在内存中(不要释放一次使用)在同一场景中。原因是图片加载到内存需要很多时间。

希望这会对你有所帮助。

【讨论】:

    【解决方案2】:

    正如 SylvainL 所说,System.gc 和朋友会收集完整的垃圾,而且速度可能非常慢。 Java 机器定期运行 GC,并且根据给定时刻有多少可用内存来微调周期。

    对我来说最好的选择是使用某种位图池:拥有一组可以从池中获取和释放的预制位图实例,并在应用 LRU 策略的缓存中管理 Buffer 实例。

    通过适当的微调,您可以在池中创建和销毁 Bitmap 实例时获得零成本,并且包含位图数据的 Buffer 实例将根据使用情况动态加载到内存中或从内存中卸载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      • 2021-11-29
      • 2019-04-30
      • 1970-01-01
      • 2011-10-13
      • 2016-09-28
      相关资源
      最近更新 更多