【问题标题】:How does the Android Studio initiates the Garbage Collector and how does it work?Android Studio 是如何启动垃圾收集器的,它是如何工作的?
【发布时间】:2015-12-14 14:44:02
【问题描述】:

我很难找到可能的内存泄漏。 我有一个 Activity 在后台做一些繁重的工作。

完成一些任务后,应用程序消耗了太多内存。好像没有清理干净。

这是默认状态下的Activity:

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

工作后的活动:

起初我以为这一定是内存问题,导致 GC 无法正确释放内存。据我所知,如果没有对对象的引用,GC 可以释放内存。对吗?

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

如果我从 Android Studio 运行 GC,内存会被正确清理,并且我的 Activity 永远不会关闭。当分配了太多内存时,我只需要使用 Android Studio GC。

这就是我的意思:

一般来说问题是:

为什么Android Studio GC可以正常清理内存,为什么不能与自动android GC一起正常工作?

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

同时调用System.gc(); 并不能正确清理内存。

其他信息:

Moto G 第二代

Android 5.0.2。

【问题讨论】:

  • "有时候Activity或者app会关闭,我想可能是内存问题造成的。"如果应用程序死机 b/c 内存不足,您将得到一个内存不足异常,您可以在 Logcat 中清楚地看到该异常。我的预感是您的应用程序因其他原因而崩溃。尝试通过 logcat 查看崩溃原因。
  • 并发 GC 只进行部分收集,以免引起明显的暂停。显式 GC(例如由 Studio 触发的 GC)会执行完整的 GC 扫描。部分阅读:source.android.com/devices/tech/dalvik/gc-debug.html
  • @Shmuel 没有例外。甚至没有警告。
  • @oberflansch 这是在什么手机上运行的?安卓操作系统版本?请尽可能多地更新帖子。
  • @Shmuel 感谢您的付出。很难相信应用程序会关闭,我知道。这可能与android版本有关。但我通常对 GC 行为感兴趣。抱歉,如果我没有明确说明这一点。这个结束的问题只是一些背景信息。

标签: java android garbage-collection


【解决方案1】:

由于多种原因,可能会发生内存泄漏。一个常见的原因是位图未正确回收。内存泄漏的其他根源是将上下文保存在对象中。例如,您启动一​​个异步任务并传递一个上下文,因为您稍后需要它。在异步任务运行时,它会保留对上下文的引用,因此整个活动都在内存中。这在匿名和内部类中也很常见,它们引用了通常是片段或活动的父类。

我建议您使用 library leak canary 来发现内存泄漏并使用 Android 工具来跟踪分配,以便准确发现内存泄漏发生的位置。

【讨论】:

  • 感谢您的回答。你提到了常见的原因,内存泄漏是如何发生的。基本上都是因为剩余的引用权。但就我而言,Android Studio GC 调用正在正确清理所有内容。所以如果有一些奇怪的引用,GC应该无法清理它们吧?
  • 不完全是。您可以退出一项活动,但仍保留参考几秒钟。因此,当您在几秒钟后运行 GC 时,它会清理该内存。我遇到了我从几个活动返回并出现内存溢出的情况,因为可能正在回收位图并延迟 GC 以释放该内存,因此发生了内存不足的情况。默认情况下,如果没有必要,GC 不会释放内存(它没有达到允许的最大内存量)。这也可能是您的其他问题。
  • 我很高兴看到这个帖子,而且它是最近的。你有没有@oberflansch 找到那个 android studio 的 GC 效果更好的原因?我正在处理应用程序使我内存不足并且程序崩溃的相同情况。我在我的应用程序中发现导致内存问题的一件事是因为我在资源中使用的所有 PNG 图像都太大了。我想知道为什么即使类中的所有引用实际上都已关闭,android 也不会在 Activity 关闭后自行 GC ......每次创建新 Activity 时,内存都会不断增加,直到它死亡
  • @CaoFelix 好吧,我不会说它更好...默认的 Android GC 仅在需要时尝试清理内存。 Android Studio GC 执行完整的 GC 并试图释放所有内容。 (这需要更多时间并可能导致更多滞后)。最后我的问题是,gfx 内存没有正确清理(不包括在内存跟踪器中)。这导致了内存泄漏。所以有时 GC 不 GC 因为它认为还不需要(对于堆)。
【解决方案2】:

也许您可以尝试在繁重的处理代码中定期显式调用System.gc();

【讨论】:

  • 对不起,我忘记了。我已经试过了,它不起作用。
  • 如果确实存在内存泄漏,那么调用 System.gc() 将无济于事,内存仍将通过代码中某处的引用保留。
  • @Shmuel 是的,但是 OP 说当他按下 android studio 上的 GC 按钮时应用程序不会崩溃,我想这是在调用 System.gc(),因此我的建议。
  • 我认为应用程序不会因内存泄漏而崩溃。这些症状听起来不像是记忆问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-31
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
相关资源
最近更新 更多