我看过很多Android答案,建议在某些情况下调用垃圾收集器。
在进行内存耗尽操作之前,在Android中请求垃圾收集器是一个好习惯吗?如果没有,如果我收到OutOfMemory
错误,我应该只调用它吗?
在使用垃圾收集器之前还有其他我应该使用的东西吗?
答案 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导致的暂时“暂停”, 建议在每个位图分配之前执行此操作
。最佳设计是:
通过显示的if / recycle / null
代码免费不再需要的所有位图。 (提出一个方法来帮助解决这个问题。)
System.gc();
分配新的位图。
答案 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的ArrayMap
和SparseArray
而不是{{ 1}} S)。
答案 10 :(得分:2)
Xamarin开发人员的快速说明。
如果您想在Xamarin.Android应用中致电System.gc()
,请拨打Java.Lang.JavaSystem.Gc()