4

随着时间的推移,我的 android 应用程序占用了越来越多的内存。我进行了堆转储并使用 MAT 对其进行了分析。

这是主要的泄漏嫌疑人:

因此,在我退出应用程序(使用后退按钮)之后,我的一项活动似乎没有从内存中清除,然后当我重新启动应用程序时,会创建一个新实例并填充内存。

现在,如果它们是 PhantomReferences,为什么一段时间后或当我退出应用程序时内存没有被清除?即使我使用其他应用程序等,内存也永远不会清除。完全关闭应用程序的唯一方法是使用任务管理器手动终止应用程序。

我能做些什么来避免这种无政府状态的内存消耗?

编辑:

我发现了问题!每个活动都使用 Thread.setDefaultUncaughtExceptionHandler() 设置 CustomExceptionHandler,并且 CustomExceptionHandler 保持对上下文的引用。所以我摆脱了上下文引用,并在 onDestroy() 方法中“取消”了 DefaultUncaughtExceptionHandler。现在真的好多了!

4

2 回答 2

5

我通常遵循的一些减小应用程序大小的通用方法是:

  • 在将 Intent 传递给下一个活动的下方调用 finish(),这将避免堆栈堆积并有助于 gc(垃圾收集)
  • 如果您没有使用共享首选项来保存数据,请在退出时通过调用 System.exit() 刷新它们
  • 如果您发现任何未在最终程序中使用的可绘制图像/布局 xmls/java 类,请确保将它们从项目中删除
  • 图像必须是 .png,因为 JPEG 图像占用大量内存。
  • 在使用数据库(sqlite、内部数据库等)的情况下,更好的方法是使用“try/catch/finally”块,在尝试打开数据库时,在最后关闭它,这将避免由于不使用而导致的内存泄漏关闭游标或数据库。
  • 使用 AsyncTask 而不是线程。在 onPostExecute() 函数中,关闭进度对话框(如果有)。
于 2012-06-20T10:13:53.470 回答
5

我会使用 MAT 的支配树功能来找出这些引用之上的内容,这可能会让你知道哪个Activity是罪魁祸首。

确保你没有通过Context任何地方并持有对它的引用,这是一个经典的 android 内存泄漏,它真的很容易做到!

尽管一些静态分析工具对此不以为然,但在您的onDestroy()方法中,您Activity可以使用null所有局部变量(基元除外),它有时有助于轻推垃圾收集器,并且可以更轻松地分析 MAT 中的堆转储。

于 2012-06-20T10:21:35.240 回答