在开发应用程序时,我注意到它最终崩溃了,因为 JVM 无法分配更多内存。使用 adb shell dumpsys meminfo 命令,我可以看到分配的 native 堆在切换 Activity 时增长,直到它接近 16M,然后崩溃。我相信我现在已经更正了代码以阻止这种情况发生,但我注意到 ..meminfo 返回的数字略有不同,现在总体上似乎略有上升。
基本上我不确定当我启动和停止应用程序时它们是否应该返回相同的值。我有这些数字,但我不确定它们是否表示我有内存泄漏:
在主屏幕,内存中的应用程序(在 DDMS 中看到的 PID),但没有运行
adb shell dumpsys meminfo(相关PID)给出:
native dalvik other total
size: 5248 4039 N/A 9287
allocated: 5227 3297 N/A 8524
free: 12 742 N/A 754
(Pss): 2183 3534 1726 7443
(shared dirty): 1976 4640 876 7492
(priv dirty): 2040 1664 940 4644
应用程序从主屏幕启动,启动的 Activity 是:
启动画面 -> 选择模式 -> Activity 1,然后使用返回按钮全部退出, 直到回到主屏幕
meminfo 现在:
native dalvik other total
size: 5572 4231 N/A 9803
allocated: 5497 3153 N/A 8650
free: 74 1078 N/A 1152
(Pss): 2479 3614 1742 7835
(shared dirty): 1976 4632 876 7484
(priv dirty): 2336 1740 956 5032
过程重复:
native dalvik other total
size: 5696 4231 N/A 9927
allocated: 5211 2949 N/A 8160
free: 392 1282 N/A 1674
(Pss): 2515 3713 1742 7970
(shared dirty): 1976 4632 876 7484
(priv dirty): 2372 1840 956 5168
Eclipse 内存分析器工具(我没有找到所有信息)报告以下内容 “泄密嫌疑人”:
3,143 instances of "java.lang.Class", loaded by "<system class loader>" occupy 736,760 (35.69%) bytes.
Biggest instances:
class com.ibm.icu4jni.util.Resources$DefaultTimeZones @ 0x40158fe0 - 165,488 (8.02%) bytes.
class android.text.Html$HtmlParser @ 0x400eebd8 - 126,592 (6.13%) bytes.
class com.google.googlenav.proto.GmmMessageTypes @ 0x43d183d8 - 56,944 (2.76%) bytes.
class org.apache.harmony.security.fortress.Services @ 0x40071430 - 51,456 (2.49%) bytes.
class android.content.res.Resources @ 0x4004df38 - 33,584 (1.63%) bytes.
class android.text.AutoText @ 0x400f23c8 - 31,344 (1.52%) bytes.
Keywords
java.lang.Class
Details »
Problem Suspect 2
8,067 instances of "java.lang.String", loaded by "<system class loader>" occupy 497,304 (24.09%) bytes.
Keywords
java.lang.String
Details »
Problem Suspect 3
54 instances of "org.bouncycastle.jce.provider.X509CertificateObject", loaded by "<system class loader>" occupy 256,024 (12.40%) bytes. These instances are referenced from one instance of "java.util.HashMap$HashMapEntry[]", loaded by "<system class loader>"
Keywords
org.bouncycastle.jce.provider.X509CertificateObject
java.util.HashMap$HashMapEntry[]
所有评论将不胜感激
最佳答案
在 MAT 中,我几乎从未遇到过实际上是泄漏的“泄漏嫌疑人”。您真正要寻找的是在 GC 扫描后保留的对象,而这些对象不应该保留。
例如,假设我有一个 Dashboard Activity ,可以启动 Activity A 和 B。我启动 Dashboard,然后启动 Activity A,按返回按钮,启动 Activity B,然后按返回按钮。
使用 Eclipse Debug View ,您可以通过“Cause GC”按钮强制执行 GC 收集事件。现在,单击“转储 HPROF 文件”按钮并启动 MAT。点击“支配树”链接。
此时,我希望与 Activity A 和 B 相关的任何内存都被作为垃圾收集,除非代码中出现错误。通常,这就是我认为应用程序中的“内存泄漏”。
这通常是由于保留的上下文而发生的,这会占用大量内存,因为上下文通常代表大型组件( Activity 、服务等)。
任何在支配树中看起来可疑的东西都可以通过“路径到 GC 根”->“排除弱引用”选项(通过右键菜单可用)最容易地进行调查。 path2gc Root View 可能是查找哪些对象持有对无法释放的对象的引用的最简单方法。
一旦发现意外引用被保留,可能需要更多地挖掘代码才能理解原因。如果它与系统/操作系统组件有关,grepcode 是你的 friend :)
关于android - 如何判断 Android 应用程序是否真的在泄漏内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5097211/