在开发应用程序时,我注意到它最终崩溃了,因为JVM无法分配更多内存.使用adb shell dumpsys meminfo命令,我可以看到分配的本机堆在切换活动时增长,直到它接近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
Run Code Online (Sandbox Code Playgroud)
应用程序从主屏幕开始,开始的活动是:
启动画面 - >选择模式 - >活动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
Run Code Online (Sandbox Code Playgroud)
过程重复:
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
Run Code Online (Sandbox Code Playgroud)
Eclipse Memory Analyzer Tool(我找不到所有信息)报告了以下"泄密嫌疑人":
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[]
Run Code Online (Sandbox Code Playgroud)
将非常感谢所有评论
在MAT中,我几乎从未遇到过实际上是泄漏的"泄漏嫌疑人".您真正需要的是在GC扫描后保留的对象,这些对象不应该被保留.
例如,假设我有一个可以启动活动A和B的仪表板活动.我启动仪表板,然后启动活动A,按后退按钮,启动活动B,然后按后退按钮.
使用Eclipse Debug视图,可以通过"Cause GC"按钮强制执行GC收集事件.现在,单击"转储HPROF文件"按钮并启动MAT.单击"Dominator Tree"链接.
此时,除非代码中出现错误,否则我希望与活动A和B相关的任何内存都被收集为垃圾.通常情况下,这就是我认为应用程序中的"内存泄漏".
这通常是由于保留的上下文而发生的,这可能会占用大量内存,因为上下文通常代表大型组件(活动,服务等).
通过"GC根路径" - >"排除弱引用"选项(通过右键单击菜单可以),可以最容易地调查在Dominator Tree中看起来可疑的任何内容.path2gc根视图可能是查找哪些对象持有对象引用以使它们无法释放的最简单方法.
一旦发现保留了意外的引用,就可以通过代码更深入地了解原因.如果它与系统/ OS组件有关,grepcode是你的朋友:)
接收者的注册和注销会导致内存泄漏
例如,如果您已经使用 registerReceiver() 注册了接收器,并且在应用程序中您尝试重新注册它而不取消注册,那么它也会导致内存泄漏问题。
通过调试和错误修复来了解这个东西。
| 归档时间: |
|
| 查看次数: |
8593 次 |
| 最近记录: |