Android 6:应用程序每次启动时使用更多内存
Android 6: App uses more memory each time it's started
三星 Galaxy S6 Android 6.0.0 和 6.0.1
我的应用程序运行良好,代码分析显示没有内存泄漏。 SmartManager 显示该应用程序使用了大约 40MB 的内存。我终止了该应用程序(使用 "currently running apps" 概览--- 不确定英文怎么称呼,抱歉。phone 左下角的键显示了所有 运行 应用程序...),然后重新启动它。
现在 SmartManager 不再为我的应用程序显示 ~40MB 内存,而是……更多。 50. 100. 400. 它各不相同,但每次都在增长。一段时间后,我的应用程序实际上 崩溃 OutOfMemoryException
。有时甚至 "out-of-memory while trying to throw an OutOfMemoryException"...
我必须卸载并重新安装该应用程序才能重置其内存消耗。相同的 APK 在我测试过的所有其他 phones 上运行正确(例如 S5 和 Android 5.0)。不知道是什么原因造成的。不知道 可能 是什么原因造成的!任何 help/hints/suggestions...?
编辑: S5 上的行为与 Android 6.0.1 相同,但 不是 S5 上的 Android 5.0!
Edit2: 谢谢大家的贡献。我仍然没有满意的答案,但提到了一些我会研究的想法。大多数人都关注 MemLeak 问题,虽然这听起来很合理,但我想强调 Android 4 或 5 没有发生泄漏,只有 6。(我还没有测试 7。)此外,泄漏仅在我强行终止应用程序时发生(有时我需要这样做以测试正确的关闭和重新启动行为),并且仅在没有附加调试器的情况下发生(这使得 testing/debugging 这种行为在背后很痛苦).
应用启动一项服务作为绑定服务。绑定到应用程序上下文——根据文档,当应用程序停止时,它应该自行清理。
不幸的是,这个赏金的时间是 运行。到目前为止,上述服务似乎是我的问题最有可能的根源。因此,我将奖励 Qamar,因为他是第一个在评论和回答中提到这一点的人。其他人,非常感谢你并投赞成票。
如果您自己做错了什么,请分析您的代码和图像。就像非常大的可绘制图像。确保你正确地实现了回收器或列表视图。
以下链接可能对您有所帮助。
使用 leakcanary 库检测并确保没有泄漏
Detect when user kill app from reccent apps
从内存监视器调用 gc Android Studio 以获得正确的内存使用值导致 gc 不 运行 频繁。
使用大堆大小。 <application android:largeHeap="true"
清单
使用应用上下文启动服务
startService(new Intent(getApplicationContext(),MyService.class));
您的应用程序有一些线程是计时器任务,它们一次又一次地创建,它们正在使用许多与网络相关的资源,因此您的堆大小不断增加,有时您的应用程序内存不足并崩溃。
在 Android Studio 中,单击屏幕底部的 Android Monitor
。单击选项卡 Monitors
。您会看到您的应用程序使用的内存图表。现在点击垃圾车旁边的项目Dump Java Heap
。系统开始收集信息并创建转储文件。您可以在 Android Studio window 右上角的 Analyze Tasks
选项卡中打开文件。按绿色箭头找到 类 泄漏内存。当您单击泄漏 activity 时,您会看到 window Reference Tree
。遍历树,找到深度为零的成员。那就是内存泄漏。
有些人认为任务杀手在 Android 上很重要。通过在后台关闭应用程序 运行ning,您将获得更高的性能和电池寿命 - 无论如何,这就是想法。实际上,任务杀手可以减少您的 performance.Android 不是 Windows 并且不像 Windows 那样管理流程。与 Windows 不同,那里有关闭应用程序的明显方法,但没有明显的方法来“关闭”Android 应用程序。这是设计使然,而不是 problem.When 您离开 Android 应用程序,返回主屏幕或切换到另一个应用程序,该应用程序在后台保持“运行ning” .在大多数情况下,应用程序将在后台暂停,不占用 CPU 或网络资源。当然,某些应用程序将继续在后台使用 CPU 和网络资源——例如,音乐播放器、文件下载程序或在 background.When 中同步的应用程序,您返回到之前的应用程序最近使用,Android“取消暂停”那个应用程序,你从你离开的地方继续。这很快,因为该应用程序仍存储在您的 RAM 中并准备好再次使用,因此不会消耗更多资源。
聪明的经理这样的任务杀手认为他们比 Android 更了解。它们 运行 在后台自动退出应用程序并将它们从 Android 的内存中删除。它们也可能允许您自己强制退出应用程序,但您不必这样做 normally.If 任务杀手会从您的 RAM 中删除一个应用程序,然后您再次打开该应用程序,该应用程序的运行速度会变慢load as Android 被迫从您设备的 storage.Further 加载它 s6 具有智能管理器,可以用作电池和存储设置的小部件或快捷方式,但是您应该避免使用“全部清除”优化功能。据说此功能可以提高设备性能 - 正如 Clean Master 应用程序旨在实现的那样 - 但其实际影响值得怀疑。
这意味着虽然有时您仍然会杀死一个应用程序,但它仍然可以在堆上留下痕迹,因此下次您启动它时,它会显示更多的已使用存储量,这也使默认 maxMemory()
的概念失败,并且该应用程序最终可能crash.Further 此类泄漏很难跟踪,因为它们与您首先杀死的应用程序没有直接关联 instance.But 有时即使在杀死应用程序之后,某些功能(如获得的资源)可能会 运行ning背景甚至应用程序都不知道 them.i.e 不明显 leaks.Thus 你可能想使用 maxMemory()
可以如下调用(例如,在您的主要 activity 的 onCreate()
方法中):
Runtime rt = Runtime.getRuntime();
long maxMemory = rt.maxMemory();
Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory));
此方法告诉您您的应用程序允许使用的堆总字节数。
最佳行为:
应用程序可以在后台 "running" 运行,而不会有任何进程占用 phone 的资源。 Android 将应用程序保存在内存中,以便更快地启动并 returns 恢复到之前的状态。当您的 phone 运行 内存不足时,Android 将自动开始自行终止任务,从您有一段时间未使用的任务开始。
你应该怎么做
也就是说,并非所有应用程序都是生而平等的。你们中的许多人过去都使用过任务杀手,实际上发现在释放内存后,您的 phone 工作得更好了。这更有可能是因为您杀死了一个编码不当的不良应用程序,并且(例如)一直尝试连接到互联网,即使它不应该。您体验到的任何性能提升更有可能是因为您终止了正确的应用程序,而不是因为您释放了内存负载(或者,在许多情况下,这只是安慰剂)。不要杀死所有这些应用程序,而是找出哪些应用程序实际上导致了 problems.using 任务杀手处理行为不端的应用程序就像使用霰弹枪杀死苍蝇 – 你可能会解决你的问题,但你正在造成process.Now 中还有很多其他损坏
由于 S6 有 3 GB 的内存,它应该不会有问题,但是智能管理器的实现可能会导致某些应用程序出现问题并且不一定 android 版本 dependent.Also 堆大小往往更多地基于屏幕分辨率,因为更高分辨率的屏幕往往想要操作更大的位图。
在这种情况下,您不应使用任务杀手,而应识别错误的应用程序并将其卸载或调试,然后将其替换为可以正常运行的应用程序。要确定出现问题的应用,您可以尝试
Watchdog Task Manager app
– 它会显示哪些应用程序实际在后台使用 CPU,而不是哪些应用程序无害地存储在内存中。
迷人的事实:
CyanogenMod, the popular community-developed Android ROM, won’t even
accept bug reports from users using task killers, saying that they
cause more problems than they solve.
如果您可以立即尝试关注,首先转到设置 > 声音和通知 > 应用通知 > select 智能管理器和 select 在锁定屏幕上隐藏内容
然后再次返回设置,转到锁屏和安全>设备安全>禁用 KNOX 主动保护并停用 KNOX 主动保护下方的反恶意软件选项
在锁定屏幕和安全中转到其他安全设置 > 禁用发送安全报告并进入使用数据访问 > 禁用智能管理器,然后重新启动你的 device.Now 查看应用程序是否正常工作 Also see performace concerns with s6
三星 Galaxy S6 Android 6.0.0 和 6.0.1
我的应用程序运行良好,代码分析显示没有内存泄漏。 SmartManager 显示该应用程序使用了大约 40MB 的内存。我终止了该应用程序(使用 "currently running apps" 概览--- 不确定英文怎么称呼,抱歉。phone 左下角的键显示了所有 运行 应用程序...),然后重新启动它。
现在 SmartManager 不再为我的应用程序显示 ~40MB 内存,而是……更多。 50. 100. 400. 它各不相同,但每次都在增长。一段时间后,我的应用程序实际上 崩溃 OutOfMemoryException
。有时甚至 "out-of-memory while trying to throw an OutOfMemoryException"...
我必须卸载并重新安装该应用程序才能重置其内存消耗。相同的 APK 在我测试过的所有其他 phones 上运行正确(例如 S5 和 Android 5.0)。不知道是什么原因造成的。不知道 可能 是什么原因造成的!任何 help/hints/suggestions...?
编辑: S5 上的行为与 Android 6.0.1 相同,但 不是 S5 上的 Android 5.0!
Edit2: 谢谢大家的贡献。我仍然没有满意的答案,但提到了一些我会研究的想法。大多数人都关注 MemLeak 问题,虽然这听起来很合理,但我想强调 Android 4 或 5 没有发生泄漏,只有 6。(我还没有测试 7。)此外,泄漏仅在我强行终止应用程序时发生(有时我需要这样做以测试正确的关闭和重新启动行为),并且仅在没有附加调试器的情况下发生(这使得 testing/debugging 这种行为在背后很痛苦).
应用启动一项服务作为绑定服务。绑定到应用程序上下文——根据文档,当应用程序停止时,它应该自行清理。 不幸的是,这个赏金的时间是 运行。到目前为止,上述服务似乎是我的问题最有可能的根源。因此,我将奖励 Qamar,因为他是第一个在评论和回答中提到这一点的人。其他人,非常感谢你并投赞成票。
如果您自己做错了什么,请分析您的代码和图像。就像非常大的可绘制图像。确保你正确地实现了回收器或列表视图。 以下链接可能对您有所帮助。
使用 leakcanary 库检测并确保没有泄漏
Detect when user kill app from reccent apps
从内存监视器调用 gc Android Studio 以获得正确的内存使用值导致 gc 不 运行 频繁。
使用大堆大小。
<application android:largeHeap="true"
清单使用应用上下文启动服务
startService(new Intent(getApplicationContext(),MyService.class));
您的应用程序有一些线程是计时器任务,它们一次又一次地创建,它们正在使用许多与网络相关的资源,因此您的堆大小不断增加,有时您的应用程序内存不足并崩溃。
在 Android Studio 中,单击屏幕底部的 Android Monitor
。单击选项卡 Monitors
。您会看到您的应用程序使用的内存图表。现在点击垃圾车旁边的项目Dump Java Heap
。系统开始收集信息并创建转储文件。您可以在 Android Studio window 右上角的 Analyze Tasks
选项卡中打开文件。按绿色箭头找到 类 泄漏内存。当您单击泄漏 activity 时,您会看到 window Reference Tree
。遍历树,找到深度为零的成员。那就是内存泄漏。
有些人认为任务杀手在 Android 上很重要。通过在后台关闭应用程序 运行ning,您将获得更高的性能和电池寿命 - 无论如何,这就是想法。实际上,任务杀手可以减少您的 performance.Android 不是 Windows 并且不像 Windows 那样管理流程。与 Windows 不同,那里有关闭应用程序的明显方法,但没有明显的方法来“关闭”Android 应用程序。这是设计使然,而不是 problem.When 您离开 Android 应用程序,返回主屏幕或切换到另一个应用程序,该应用程序在后台保持“运行ning” .在大多数情况下,应用程序将在后台暂停,不占用 CPU 或网络资源。当然,某些应用程序将继续在后台使用 CPU 和网络资源——例如,音乐播放器、文件下载程序或在 background.When 中同步的应用程序,您返回到之前的应用程序最近使用,Android“取消暂停”那个应用程序,你从你离开的地方继续。这很快,因为该应用程序仍存储在您的 RAM 中并准备好再次使用,因此不会消耗更多资源。
聪明的经理这样的任务杀手认为他们比 Android 更了解。它们 运行 在后台自动退出应用程序并将它们从 Android 的内存中删除。它们也可能允许您自己强制退出应用程序,但您不必这样做 normally.If 任务杀手会从您的 RAM 中删除一个应用程序,然后您再次打开该应用程序,该应用程序的运行速度会变慢load as Android 被迫从您设备的 storage.Further 加载它 s6 具有智能管理器,可以用作电池和存储设置的小部件或快捷方式,但是您应该避免使用“全部清除”优化功能。据说此功能可以提高设备性能 - 正如 Clean Master 应用程序旨在实现的那样 - 但其实际影响值得怀疑。
这意味着虽然有时您仍然会杀死一个应用程序,但它仍然可以在堆上留下痕迹,因此下次您启动它时,它会显示更多的已使用存储量,这也使默认 maxMemory()
的概念失败,并且该应用程序最终可能crash.Further 此类泄漏很难跟踪,因为它们与您首先杀死的应用程序没有直接关联 instance.But 有时即使在杀死应用程序之后,某些功能(如获得的资源)可能会 运行ning背景甚至应用程序都不知道 them.i.e 不明显 leaks.Thus 你可能想使用 maxMemory()
可以如下调用(例如,在您的主要 activity 的 onCreate()
方法中):
Runtime rt = Runtime.getRuntime();
long maxMemory = rt.maxMemory();
Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory));
此方法告诉您您的应用程序允许使用的堆总字节数。 最佳行为: 应用程序可以在后台 "running" 运行,而不会有任何进程占用 phone 的资源。 Android 将应用程序保存在内存中,以便更快地启动并 returns 恢复到之前的状态。当您的 phone 运行 内存不足时,Android 将自动开始自行终止任务,从您有一段时间未使用的任务开始。 你应该怎么做
也就是说,并非所有应用程序都是生而平等的。你们中的许多人过去都使用过任务杀手,实际上发现在释放内存后,您的 phone 工作得更好了。这更有可能是因为您杀死了一个编码不当的不良应用程序,并且(例如)一直尝试连接到互联网,即使它不应该。您体验到的任何性能提升更有可能是因为您终止了正确的应用程序,而不是因为您释放了内存负载(或者,在许多情况下,这只是安慰剂)。不要杀死所有这些应用程序,而是找出哪些应用程序实际上导致了 problems.using 任务杀手处理行为不端的应用程序就像使用霰弹枪杀死苍蝇 – 你可能会解决你的问题,但你正在造成process.Now 中还有很多其他损坏 由于 S6 有 3 GB 的内存,它应该不会有问题,但是智能管理器的实现可能会导致某些应用程序出现问题并且不一定 android 版本 dependent.Also 堆大小往往更多地基于屏幕分辨率,因为更高分辨率的屏幕往往想要操作更大的位图。 在这种情况下,您不应使用任务杀手,而应识别错误的应用程序并将其卸载或调试,然后将其替换为可以正常运行的应用程序。要确定出现问题的应用,您可以尝试
Watchdog Task Manager app
– 它会显示哪些应用程序实际在后台使用 CPU,而不是哪些应用程序无害地存储在内存中。
迷人的事实:
CyanogenMod, the popular community-developed Android ROM, won’t even accept bug reports from users using task killers, saying that they cause more problems than they solve.
如果您可以立即尝试关注,首先转到设置 > 声音和通知 > 应用通知 > select 智能管理器和 select 在锁定屏幕上隐藏内容
然后再次返回设置,转到锁屏和安全>设备安全>禁用 KNOX 主动保护并停用 KNOX 主动保护下方的反恶意软件选项
在锁定屏幕和安全中转到其他安全设置 > 禁用发送安全报告并进入使用数据访问 > 禁用智能管理器,然后重新启动你的 device.Now 查看应用程序是否正常工作 Also see performace concerns with s6