在处理位图时调用System.gc()和Thread.sleep()是否有意义? [英] Does it make sense to call System.gc() and Thread.sleep() when working on Bitmaps?

查看:143
本文介绍了在处理位图时调用System.gc()和Thread.sleep()是否有意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我跳到Android项目,该项目分配了很多Bitmaps.我在这里遇到了这段代码:

I've jumped to Android project, which allocated a lot of Bitmaps . I've met there this code:

  System.gc();
  try {
    b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
  } catch (OutOfMemoryError e) {
    System.gc();
    try {
      Thread.sleep(100);
    } catch (InterruptedException e1) {
      log.error("Failed to sleep.");
    }
    try {
      b = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
    } catch (OutOfMemoryError e1) {
      log.error("Error", e1);
    }
  }

并且我开始怀疑在调用System.gc()之后是否有一段时间可以休眠线程? 我已经对System.gc()进行了一些研究,但发现了一些有关其工作方式的信息:

and I've started to wonder if it have any sense to sleep Thread for a while after System.gc() was called? I've made some research about System.gc() on my own and I found few info about how it works:

Patrick Dubroy 说,在Android> = Honeycomb上进行垃圾收集大约需要5毫秒(优化并发).

Patrick Dubroy said that garbage collecting on Android >= Honeycomb it takes about 5ms (it is optimized and concurrent).

此外,在一些地方,我发现了一些信息,即调用System.gc()只是运行垃圾收集器的建议.上面的代码是项目的一部分,该项目在过去的两年中得到了增强,我认为Thread.sleep是解决此时发生问题的一种变通方法.

Moreover in few places I found info, that calling System.gc() is just a suggestion to run garbage collector. Above code is part of project which is enhanced for last 2 years and I suppose that this Thread.sleep is some workaround for problems which occurs on this time.

有什么想法吗?

推荐答案

调用Thread.Sleep()看起来是为了给垃圾回收器足够的时间来执行其工作,否则,如果发生OutOfMemoryError,尝试重新创建Bitmap第一次尝试.在第二次尝试时,较低的标准用于消耗更少的内存:RGB_565而不是ARGB_8888.

Looks like Thread.Sleep() is called to give the garbage collector enough time to do its job bebore trying to recreate the Bitmap should an OutOfMemoryError have occurred at first attempt. At second attempt, lower standards are used to consume less memory: RGB_565 instead of ARGB_8888.

最好在第一次尝试创建Bitmap之前测试可用内存量(对并发应用程序更有效/更容易/更强大/危险性更低),而不是捕获OutOfMemoryError.

It would be better (more efficient / easier to read / stronger / less dangerous for concurrent applications) to test the amount of available memory before trying to create the Bitmap the first time, rather than catching OutOfMemoryError.

Thread.sleep(100)方面,它假定将启动垃圾回收并在100ms内完成垃圾回收,这绝对是任意的.它可能尚未启动,可能仍在运行...

Thread.sleep(100), on its side, assumes that the garbage collection will be initiated and will complete within 100ms, which is absolutely arbitrary. It may have not started yet, it may be still running...

无论如何,在这里调用System.gc()并没有帮助,因为无论如何都会收集垃圾. VM会检测到这一点,并且在有大量垃圾收集的情况下不会等待.

And anyway, calling System.gc() is not helpful here as the garbage will be collected anyway. The VM detects that and won't wait should there be a lot of garbage to collect.

所以我的建议是:

  • 忘记这些System.gc()Thread.Sleep()调用.他们没有效率/没有帮助.
  • 在第一次尝试创建Bitmap之前,请测试可用内存量.您可以确定将来产生的Bitmap的大小,因为您知道它的大小和编码. (引用:运行时 ActivityManager )
  • 如果剩余的内存量少,为什么如果结果Bitmap合适(16位RGB而不是32位ARGB),则不降低标准.
  • 这应该是不够的,记录错误和/或显示警报(取决于您的应用程序,我不知道上下文)是可以的.
  • Forget about these System.gc() and Thread.Sleep() calls. They are not efficient/helpful.
  • Test the amount of available memory before trying to create the Bitmap the first time. You can determine the size of the future resulting Bitmap as you know its size and encoding. (Refs: Runtime and ActivityManager)
  • Should the amount of memory left be low, why not reducing the standards if the resulting Bitmap fits (16 bits RGB instead of 32 bits ARGB).
  • Should this be unsufficient, logging an error and/or displaying an alert (depending on your app, I don't know the context) is fine.

Android团队的两篇有趣的相关文章:

Two interesting related articles from the Android team:

  • Managing Your App's Memory
  • Managing Bitmap Memory

这篇关于在处理位图时调用System.gc()和Thread.sleep()是否有意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆