首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何判断Android应用程序是否真的存在内存泄漏?

如何判断Android应用程序是否真的存在内存泄漏?
EN

Stack Overflow用户
提问于 2011-02-24 05:14:28
回答 5查看 9.2K关注 0票数 19

在开发应用程序时,我注意到它最终崩溃了,因为JVM无法分配更多的内存。使用adb shell dumpsys meminfo命令,我可以看到分配的本机堆不断增长,同时切换活动,直到它接近16M,然后崩溃。我相信我现在已经更正了代码来阻止这种情况的发生,但我注意到..meminfo返回的数字略有不同,总体上看现在似乎略有上升。

基本上,我不确定当我启动和停止应用程序时,它们是否应该返回到相同的值。我有这些数字,但我不确定它们是否表示我有内存泄漏:

在主屏幕上,应用程序在内存中(在DDMS中看到PID),但未运行

adb shell dumpsys meminfo (相关PID)给出:

代码语言:javascript
复制
                    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

应用程序从主屏幕启动,启动的活动包括:

splash screen -> select mode -> Activity 1,然后使用back按钮全部退出,直到回到主屏幕

meminfo now:

代码语言:javascript
复制
                    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

重复的过程:

代码语言:javascript
复制
                    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 Memory Analyzer工具(我不认为它提供的所有信息都很有用)报告了以下“泄漏嫌疑”:

代码语言:javascript
复制
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[]

我们将竭诚为您服务!

EN

回答 5

Stack Overflow用户

发布于 2012-09-06 09:59:28

在MAT中,我几乎从来没有遇到过真正是泄漏的“泄漏嫌疑人”。您真正要找的是在GC扫描后保留的对象,这是不应该的。

例如,假设我有一个仪表板活动,可以启动活动A和B。我启动仪表板,然后启动活动A,按后退按钮,启动活动B,然后按后退按钮。

使用Eclipse Debug视图,您可以通过“原因GC”按钮强制执行GC收集事件。现在,单击"Dump HPROF file“按钮并启动MAT。单击"Dominator Tree“链接。

此时,除非代码中有错误,否则与活动A和B相关联的任何内存都将被收集为垃圾。通常,这就是我所说的应用程序中的“内存泄漏”。

这种情况最常见的原因是保留的上下文,由于上下文通常表示大型组件(活动、服务等),因此可能会占用大量内存。

通过“GC根路径”->“排除弱引用”选项(通过右键菜单可用),可以最容易地调查在主导树中看起来可疑的任何东西。path2gc根视图可能是找出哪些对象持有对对象的引用从而无法释放这些对象的最简单方法。

一旦您发现意外的引用被保留,可能需要更深入地挖掘代码才能理解原因。如果与系统/OS组件有关,grepcode是您的朋友:)

票数 6
EN

Stack Overflow用户

发布于 2011-02-24 17:09:08

接收方的注册和注销将导致内存泄漏

例如,如果你已经用registerReceiver()注册了接收器,并且在应用程序中它自己,你试图在不做注销的情况下重新注册它,那么它会导致你的内存泄漏问题。

我是从调试和bug修复中了解到这个东西的。

票数 1
EN

Stack Overflow用户

发布于 2011-03-01 11:49:31

根据我创建Android应用程序的经验,这个操作系统似乎在内存中留下了很多垃圾。然而,当设备需要它来做一些重要的事情时,它会(几乎不加区别地)获取它需要的任何东西。即使它覆盖了另一个当前打开的应用程序中的数据。

除此之外,在背景中可能还有其他几件事会影响你的数据,所以我不认为我们可以从中得出任何确凿的信息。如果您创建的应用程序正在泄漏,那么很可能您正在做的某些操作也会在任何其他基于Java的环境中导致内存泄漏。像这样的一篇文章:http://www.ibm.com/developerworks/library/j-leaks/应该有助于修复大多数泄漏的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5097211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档