Java Android中的垃圾收集器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3117429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Garbage collector in Android
提问by hpique
I have seen many Android answers that suggest calling the garbage collector in some situations.
我看到很多 Android 答案都建议在某些情况下调用垃圾收集器。
Is it a good practice to request the garbage collector in Android before doing a memory-hungry operation? If not, should I only call it if I get an OutOfMemory
error?
在执行内存饥渴的操作之前在 Android 中请求垃圾收集器是一个好习惯吗?如果没有,我应该只在OutOfMemory
出现错误时调用它吗?
Are there other things I should use before resorting to the garbage collector?
在诉诸垃圾收集器之前,我还应该使用其他东西吗?
采纳答案by steve
For versions prior to 3.0 honeycomb: Yes, do callSystem.gc()
.
对于3.0 Honeycomb之前的版本:是的,请调用System.gc()
.
I tried to create Bitmaps, but was always getting "VM out of memory error". But, when I called System.gc()
first, it was OK.
我尝试创建位图,但总是出现“VM 内存不足错误”。但是,当我System.gc()
第一次打电话时,没关系。
When creating bitmaps, Android often fails with out of memory errors, and does not try to garbage collect first. Hence, call System.gc()
, and you have enough memory to create Bitmaps.
创建位图时,Android 经常会因内存不足错误而失败,并且不会先尝试进行垃圾收集。因此,调用System.gc()
,您就有足够的内存来创建位图。
If creating Objects, I think System.gc
will be called automatically if needed,
but notfor creating bitmaps. It just fails.
如果创建对象,我认为System.gc
会在需要时自动调用,但不会用于创建位图。它只是失败了。
So I recommend manually calling System.gc()
before creating bitmaps.
所以我建议System.gc()
在创建位图之前手动调用。
回答by Andreas Dolk
If you get an OutOfMemoryError then it's usually too late to call the garbage collector...
如果您收到 OutOfMemoryError 错误,那么调用垃圾收集器通常为时已晚......
Here is quote from Android Developer:
以下是来自 Android 开发人员的报价:
Most of the time, garbage collection occurs because of tons of small, short-lived objects and some garbage collectors, like generational garbage collectors, can optimize the collection of these objects so that the application does not get interrupted too often. The Android garbage collector is unfortunately not able to perform such optimizations and the creation of short-lived objects in performance critical code paths is thus very costly for your application.
大多数情况下,垃圾收集的发生是因为大量的小、寿命短的对象,而一些垃圾收集器,如分代垃圾收集器,可以优化这些对象的收集,这样应用程序就不会经常被中断。遗憾的是,Android 垃圾收集器无法执行此类优化,因此在性能关键代码路径中创建短期对象对于您的应用程序来说非常昂贵。
So to my understanding, there is no urgent need to call the gc. It's better to spend more effort in avoiding the unnecessary creation of objects (like creation of objects inside loops)
所以据我所知,没有迫切需要调用 gc。最好花更多的精力来避免不必要的对象创建(例如在循环内创建对象)
回答by perdian
There is no need to call the garbage collector after an OutOfMemoryError
.
不需要在 之后调用垃圾收集器OutOfMemoryError
。
It's Javadoc clearly states:
它的 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.
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.
So, the garbage collector already tried to free up memory before generating the error but was unsuccessful.
因此,垃圾收集器在产生错误之前已经尝试释放内存但没有成功。
回答by Thomas Pornin
Generally speaking, in the presence of a garbage collector, it is nevergood practice to manually call the GC. A GC is organized around heuristic algorithms which work best when left to their own devices. Calling the GC manually often decreases performance.
一般来说,在有垃圾收集器的情况下,手动调用 GC从来都不是一个好习惯。GC 是围绕启发式算法组织的,这些算法在留给自己的设备时效果最佳。手动调用 GC 通常会降低性能。
Occasionally, in some relatively rare situations, one may find that a particular GC gets it wrong, and a manual call to the GC may then improves things, performance-wise. This is because it is not really possible to implement a "perfect" GC which will manage memory optimally in all cases. Such situations are hard to predict and depend on many subtle implementation details. The "good practice" is to let the GC run by itself; a manual call to the GC is the exception, which should be envisioned only after an actual performance issue has been duly witnessed.
偶尔,在一些相对罕见的情况下,人们可能会发现特定的 GC 出错,然后手动调用 GC 可能会改善性能,提高性能。这是因为实际上不可能实现在所有情况下都以最佳方式管理内存的“完美”GC。这种情况很难预测,取决于许多微妙的实现细节。“好的做法”是让 GC 自己运行;手动调用 GC 是个例外,只有在适当见证实际性能问题后才应设想这种情况。
回答by yogesh
Out of memory in android application is very common if we not handle the bitmap properly, The solution for the problem would be
如果我们没有正确处理位图,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);
In the above code Have just tried to recycle the bitmap which will allow you to free up the used memory space ,so out of memory may not happen.I have tried it worked for me.
在上面的代码中刚刚尝试回收位图,这将允许您释放已用的内存空间,因此可能不会发生内存不足的情况。我试过它对我有用。
If still facing the problem you can also add these line as well
如果仍然面临问题,您也可以添加这些行
BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];
options.inPurgeable = true;
for more information take a look at this link
有关更多信息,请查看此链接
NOTE: Due to the momentary "pause" caused by performing gc, it is notrecommended to do this before eachbitmap allocation.
注意:由于执行 gc 会导致暂时的“暂停”,因此不建议在每次位图分配之前执行此操作。
Optimum design is:
优化设计是:
Free all bitmaps that are no longer needed, by the
if / recycle / null
code shown. (Make a method to help with that.)System.gc();
Allocate the new bitmaps.
通过显示的代码释放所有不再需要的位图
if / recycle / null
。(制定一个方法来帮助解决这个问题。)System.gc();
分配新的位图。
回答by prabhu
Best way to avoid OOM during Bitmap creation,
在位图创建期间避免 OOM 的最佳方法,
http://developer.android.com/training/displaying-bitmaps/index.html
http://developer.android.com/training/displaying-bitmaps/index.html
回答by Igor ?orda?
Generally speaking you should not call GC explicitly with System.gc(). There is even the IO lecture (http://www.youtube.com/watch?v=_CruQY55HOk) where they explain what the GC pauses log mean and in which they also state to never call System.gc() because Dalvik knows better than you when to do so.
一般而言,您不应使用 System.gc() 显式调用 GC。甚至还有 IO 讲座 ( http://www.youtube.com/watch?v=_CruQY55HOk),他们解释了 GC 暂停日志的含义,并且他们还声明永远不要调用 System.gc() 因为 Dalvik 知道得更好比你什么时候这样做。
On the other hand as mentioned in above answers already GC process in Android (like everything else) is sometimes buggy. This means Dalvik GC algorithms are not on par with Hotspot or JRockit JVMs and might get things wrong on some occasions. One of those occasions is when allocating bitmap objects. This is a tricky one because it uses Heap and Non Heap memory and because one loose instance of bitmap object on memory constrained device is enough to give you an OutOfMemory exception. So calling it after you don't need this bitmap any-more is generally suggested by many developers and is even considered good practice by some people.
另一方面,正如上面的答案中提到的,Android 中的 GC 过程(与其他所有内容一样)有时会出现问题。这意味着 Dalvik GC 算法无法与 Hotspot 或 JRockit JVM 相提并论,并且在某些情况下可能会出错。其中一种情况是分配位图对象时。这是一个棘手的问题,因为它使用堆和非堆内存,并且因为内存受限设备上位图对象的一个松散实例足以给您一个 OutOfMemory 异常。所以在你不再需要这个位图之后调用它——许多开发人员通常都建议这样做,甚至被一些人认为是很好的做法。
Better practice is using .recycle() on a bitmap as it is what this method is made for, as it marks native memory of the bitmap as safe to delete. Keep in mind that this is very version dependent, meaning it will generally be required on older Android versions (Pre 3.0 I think) but will not be required on later ones. Also it won't hurt much using it on newer versions ether (just don't do this in a loop or something like that). New ART runtime changed a lot here because they introduced special Heap "partition" for big objects but I think it will not hurt much to do this with ART ether.
更好的做法是在位图上使用 .recycle() ,因为它是此方法的用途,因为它将位图的本机内存标记为可以安全删除。请记住,这非常依赖于版本,这意味着旧的 Android 版本(我认为是 3.0 之前)通常需要它,但以后的版本不需要。此外,在较新版本的以太上使用它也不会造成太大伤害(只是不要在循环中执行此操作或类似操作)。新的 ART 运行时在这里发生了很大变化,因为它们为大对象引入了特殊的堆“分区”,但我认为用 ART 以太做这件事不会有太大伤害。
Also one very important note about System.gc(). This method is not a command that Dalvik (or JVMs) are obligated to respond to. Consider it more like saying to Virtual machine "Could you please do garbage collection if it's not a hassle".
也是关于 System.gc() 的一个非常重要的说明。此方法不是 Dalvik(或 JVM)必须响应的命令。认为它更像是对虚拟机说“如果不麻烦,您可以进行垃圾收集吗”。
回答by Klykoo
My app manage a lot of images and it died with a OutOfMemoryError. This helped me. In the Manifest.xml Add
我的应用程序管理了很多图像,但它因 OutOfMemoryError 而死了。这对我有帮助。在 Manifest.xml 添加
<application
....
android:largeHeap="true">
回答by cmicat
It seems System.gc()
do not work on Art Android 6.0.1 Nexus 5x, So I use Runtime.getRuntime().gc();
instead.
它似乎System.gc()
不适用于 Art Android 6.0.1 Nexus 5x,所以我Runtime.getRuntime().gc();
改为使用。
回答by Farbod Salamat-Zadeh
I would say no, because the Developer docs on RAM usagestate:
...
GC_EXPLICIT
An explicit GC, such as when you call gc()(which you should avoidcallingand instead trust the GC to run when needed).
...
...
GC_EXPLICIT
显式 GC,例如当您调用gc() 时(您应该避免调用它,而是信任 GC 在需要时运行)。
...
I've highlighted the relevant part in bold.
我用粗体突出显示了相关部分。
Have a look at the YouTube series, Android Performance Patterns- it will show you tips on managing your app's memory usage (such as using Android's ArrayMap
s and SparseArray
s instead of HashMap
s).
看看 YouTube 系列,Android 性能模式- 它将向您展示管理应用程序内存使用的技巧(例如使用 Android 的ArrayMap
s 和SparseArray
s 而不是HashMap
s)。