Android中的垃圾收集器

时间:2010-06-25 10:57:57

标签: java android garbage-collection

我看过很多Android答案,建议在某些情况下调用垃圾收集器。

在进行内存耗尽操作之前,在Android中请求垃圾收集器是一个好习惯吗?如果没有,如果我收到OutOfMemory错误,我应该只调用它吗?

在使用垃圾收集器之前还有其他我应该使用的东西吗?

11 个答案:

答案 0 :(得分:139)

对于 3.0蜂窝之前的版本:是,请致电 System.gc()

我尝试创建Bitmaps,但总是得到“VM内存不足错误”。但是,当我首先打电话给System.gc()时,没关系。

创建位图时,Android经常因内存不足而失败,不会尝试首先进行垃圾回收。因此,调用System.gc(),并且您有足够的内存来创建位图。

如果创建对象,我认为如果需要,将自动调用System.gc, 但用于创建位图。它失败了。

所以我建议在创建位图之前手动调用System.gc()

答案 1 :(得分:115)

一般来说,在存在垃圾收集器的情况下,手动调用GC是从不的好习惯。 GC围绕启发式算法进行组织,这些算法在放置到自己的设备时效果最佳。手动调用GC通常会降低性能。

偶尔,在某些相对罕见的情况下,人们可能会发现某个特定的GC出错了,然后手动调用GC可以改善性能,提高性能。这是因为实际上不可能实现“完美”的GC,它将在所有情况下以最佳方式管理内存。这种情况很难预测,并取决于许多微妙的实施细节。 “良好实践”是让GC独立运行;手动调用GC是一个例外情况,只有在实际出现性能问题后才能设想。

答案 2 :(得分:26)

如果我们不正确处理位图,Android应用程序中的内存很常见, 问题的解决方案是

if(imageBitmap != null) {
     imageBitmap.recycle();
     imageBitmap = null;
}
System.gc();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
imageBitmap = BitmapFactory.decodeFile(URI, options);
Bitmap  scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, true);
imageView.setImageBitmap(scaledBitmap);

在上面的代码中刚刚尝试回收位图,这将允许你释放已用的内存空间,因此可能不会发生内存不足。我试过它对我有效。

如果仍然遇到问题,您也可以添加这些行

BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];
options.inPurgeable = true;

了解更多信息,请查看此链接

http://voices.yahoo.com/android-virtual-machine-vm-out-memory-error-7342266.html


注意:由于执行gc导致的暂时“暂停”, 建议在每个位图分配之前执行此操作

最佳设计是:

  1. 通过显示的if / recycle / null代码免费不再需要的所有位图。 (提出一个方法来帮助解决这个问题。)

  2. System.gc();

  3. 分配新的位图。

答案 3 :(得分:19)

如果你得到一个OutOfMemoryError,那么调用垃圾收集器通常为时已晚......

以下是Android开发者的引用:

  

大多数时候,垃圾收集   因为吨很小,   短暂的物体和一些垃圾   收藏家,像世代垃圾   收藏家,可以优化   这些对象的集合使得   应用程序没有得到   经常中断。 Android   遗憾的是垃圾收集器没有   能够执行这样的优化和   创造短命的物体   性能关键代码路径是   因此对您的申请来说非常昂贵。

所以据我所知,没有迫切需要打电话给gc。最好花更多的精力避免不必要的对象创建(比如在循环中创建对象)

答案 4 :(得分:7)

我的应用管理了大量图片,并且因OutOfMemoryError而死亡。 这对我有帮助。 在Manifest.xml中 添加

<application
....
   android:largeHeap="true"> 

答案 5 :(得分:7)

似乎System.gc()无法在Art Android 6.0.1 Nexus 5x上运行,因此我改为使用Runtime.getRuntime().gc();

答案 6 :(得分:5)

一般来说,不应该使用System.gc()明确调用GC。甚至还有IO讲座(http://www.youtube.com/watch?v=_CruQY55HOk),他们解释了GC暂停日志的意思,并且他们也声明从不调用System.gc(),因为Dalvik比你知道什么时候更好。

另一方面,如上面的答案所述,Android中的GC流程(就像其他一切一样)有时会出错。这意味着Dalvik GC算法与Hotspot或JRockit JVM不相同,并且在某些情况下可能会出错。其中一种情况是分配位图对象。这是一个棘手的问题,因为它使用Heap和Non Heap内存,因为内存受限设备上的一个松散的位图对象实例足以为您提供OutOfMemory异常。因此,在您不再需要此位图之后调用它通常会被许多开发人员建议,甚至被某些人视为良好实践。

更好的做法是在位图上使用.recycle(),就像这个方法一样,因为它将位图的本机内存标记为可以安全删除。 请记住,这是非常依赖于版本的,这意味着它通常在较旧的Android版本(我认为是3.0版)上是必需的,但在以后的版本中不需要。在新版本的以太网上使用它也不会有太大的伤害(只是不要在循环或其他类似的事情中这样做)。新的ART运行时在这里发生了很大变化,因为它们引入了特殊的Heap&#34;分区&#34;对于大型物体,但我认为用ART醚来做这件事并不会太大。

还有一个关于System.gc()的重要说明。此方法不是Dalvik(或JVM)有义务响应的命令。考虑更像是对虚拟机说#34;如果不是麻烦的话,请你做垃圾收集&#34;。

答案 7 :(得分:3)

在创建位图期间避免OOM的最佳方法,

http://developer.android.com/training/displaying-bitmaps/index.html

答案 8 :(得分:2)

无需在OutOfMemoryError之后调用垃圾收集器。

这是Javadoc明确指出:

  

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

因此,垃圾收集器在生成错误之前已经尝试释放内存但是没有成功。

答案 9 :(得分:2)

我会说不,因为Developer docs on RAM usage州:

  

...
  GC_EXPLICIT

     

显式GC,例如当您致电gc()时(您应该避免调用,而是信任GC在需要时运行)。

     

...

我用粗体突出显示了相关部分。

查看YouTube系列Android Performance Patterns - 它会向您显示有关管理应用内存使用情况的提示(例如使用Android的ArrayMapSparseArray而不是{{ 1}} S)。

答案 10 :(得分:2)

Xamarin开发人员的快速说明

如果您想在Xamarin.Android应用中致电System.gc(),请拨打Java.Lang.JavaSystem.Gc()