Android Studio如何启动垃圾回收器并运行?

8

我正在努力寻找可能的内存泄漏问题。我有一个在后台执行一些繁重工作的活动。

在完成一些任务后,应用程序会消耗太多的内存。似乎它没有得到适当的清理。

这是默认状态下的Activity:

enter image description here

如果我运行Activity正在执行的任务,就会分配更多的内存。

完成一些工作后的Activity: enter image description here

起初,我认为这必须是一个内存问题,因为GC不能正确地释放内存。据我所知,如果没有对对象的引用,GC可以释放内存。这是正确的吗?

现在让我感到困惑的部分:

如果我从Android Studio运行GC,则可以正确清除内存,我的Activity永远不会关闭。当分配了太多内存时,我只需要使用Android Studio GC。 enter image description here

这就是我所说的那个。

enter image description here

一般来说,问题是:

为什么Android Studio的垃圾回收可以正确清理内存,而自动的Android GC却不能正常工作?

我知道这是一个非常普遍的问题。我只是想知道是否有不同类型的垃圾回收或类似的东西。

此外,调用System.gc();并不能正确地清理内存。

附加信息:

Moto G 2nd gen

Android 5.0.2。


有时候,Activity或应用程序会关闭。我认为这可能是由于内存问题引起的。如果应用程序因内存不足而死亡,则会收到Out-of-Memory异常,您可以在Logcat中清楚地看到。我的直觉是您的应用程序因其他原因而崩溃。尝试查看logcat以查看崩溃原因。 - Shmuel
1
并发GC仅进行部分收集,以避免引起明显的暂停。 Studio触发的显式GC会进行完整的GC扫描。一些阅读材料:https://source.android.com/devices/tech/dalvik/gc-debug.html - laalto
@Shmuel 没有异常。甚至没有警告。 - daemmie
@oberflansch 这款手机运行的是什么系统?Android版本是多少?请尽可能提供更多信息更新帖子。 - Shmuel
@Shmuel 感谢你的努力。我知道很难相信应用程序会关闭。这可能与Android版本有关。但我一般对GC行为感兴趣。如果我没有表达清楚,对不起。这个关闭问题只是一些背景信息。 - daemmie
@laalto 谢谢。这基本上就是我想要的。 - daemmie
2个回答

4
内存泄漏可能由几个原因引起。一个常见的原因是未正确回收位图。内存泄漏的另一个根源是在对象中保留上下文。例如,您启动异步任务并传递上下文,因为您稍后需要它。当异步任务正在运行时,它会保留对上下文的引用,因此整个活动都在内存中。这也很常见于具有对父类的引用的匿名和内部类,通常是片段或活动。
我建议您使用LeakCanary库来检测内存泄漏,并使用Android工具跟踪分配以精确定位内存泄漏发生的位置。

谢谢你的回答。你提到了内存泄漏发生的常见原因。基本上都是由于剩余引用,对吧?但在我的情况下,Android Studio GC调用已经正确地清理了所有内容。所以如果有一些奇怪的引用,GC就不应该能够将它们清理干净,对吧? - daemmie
不完全是这样。您可以退出一个活动,但仍保留几秒钟的引用。因此,当您在几秒钟后运行GC时,它将清理该内存。我遇到过这样的情况,我从多个活动中返回并且出现了内存溢出,因为可能正在回收位图并延迟GC以释放该内存,因此发生了内存不足的情况。默认情况下,如果不必要(未达到允许的最大内存量),GC不会释放内存。这也可能是您的其他问题。 - jorgemf
我很高兴看到这个帖子,而且它相当新。@oberflansch,你找到了Android Studio的GC为什么工作得更好的原因吗?我正在处理同样的情况,应用程序会抛出内存不足的异常并崩溃。我在我的应用程序中发现一个导致内存问题的原因是我在资源中使用的所有PNG图像都太大了。我想知道为什么Android在活动关闭后甚至在类中的所有引用实际上都关闭时不会自动进行GC...每次创建新活动时,内存使用量都会增加,直到应用程序死亡。 - Cao Felix
@CaoFelix 嗯,我不会说这样更好...默认的Android GC只在需要时清理内存。而Android Studio GC则进行完整的GC并尝试释放所有内容。(这需要更长的时间并可能导致更多的延迟)。最后我的问题是,gfx内存没有被正确清理(这不包括在内存跟踪器中)。这导致了内存泄漏。所以有时候GC不会执行,因为它认为还不需要(对于堆来说)。 - daemmie

3
也许你可以尝试在你的大量处理代码中定期显式调用System.gc();

抱歉,我忘记了。我已经尝试过那个方法,但它没有起作用。 - daemmie
如果确实存在内存泄漏,则调用 System.gc() 不会有帮助,因为内存仍然通过代码中某个地方的引用保留。 - Shmuel
@Shmuel 是的,但是OP说当他在Android Studio上按GC按钮时应用程序不会崩溃,我想这是在调用System.gc(),因此我建议这样做。 - James Wierzba
我认为应用程序不会因为内存泄漏而崩溃。症状听起来不像是内存问题。 - Shmuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接