【问题标题】:How to find root of memory leaks?如何找到内存泄漏的根源?
【发布时间】:2011-08-28 03:12:50
【问题描述】:

我的应用程序基本上是图像编辑器。有一个欢迎页面,可以打开主要活动的意图。如果在主要活动工作时方向发生变化,则内存消耗只会增加一倍并保持不变。如果我关闭主要活动转回欢迎活动并再次启动主要活动,则不会发生相同的问题。我认为所有这些都表明内存泄漏,我已经调查过自己但找不到应用程序泄漏内存的原因。我正在使用应用程序上下文,并且我的应用程序中没有静态字段。我试图转储堆并用 MAT 分析它,但是我找不到任何好的东西。我希望有人能告诉我正确的方向来找到内存泄漏的根源或其他可能的问题解释。

【问题讨论】:

  • DDMS 中的跟踪器(在 eclipse 中非常容易访问)允许程序员监控内存分配。

标签: java android memory-leaks out-of-memory heap-memory


【解决方案1】:

请记住,在 JVM 中(甚至在像 Davlik 这样的 I-can't-believe-it's-not-a-JVM)中,您使用的许多项目并不完全在您的控制之下。所以,正确的方法是找到一种方法来验证你的代码没有内存泄漏,然后你就会知道如果内存溢出,很可能是某个外部子系统,或者应用程序实际内存需求的一些预期结果。

根据您的描述,显示渲染很可能只是为每个屏幕方向保留一个延迟构建的缓存内存缓冲区。

我之所以提到这一点,是因为您已经(从您的帖子中)比较了堆转储,如果堆没有显示出对象积累的趋势,那么它很可能是库实现中包含的某些项目。我知道这是一个非常普遍的经验法则,不适用于大多数程序(因为它们可能确实包含真正的内存泄漏),但是当其他选项用尽时可能会对其进行调查。

如果您真的想验证某个特定库是否保留了屏幕方向的缓存副本,您始终可以编写一个小型“测试”程序,该程序缺少所有混淆因素(就像您的程序的其余部分一样)看看它在屏幕方向变化时的表现。

就使用VisualVM而言,它非常适合检测用户空间内存泄漏;但是,由于它在不同的架构和实现上运行,它可能会错过特定于平台的库问题。

【讨论】:

    【解决方案2】:

    VisualVM http://visualvm.java.net/
    从 1.6 的某些版本开始,它就在 JDK 发行版中

    【讨论】:

      【解决方案3】:

      Google I|O 2011 conference presentation 涵盖了此特定场景。我建议观看演示文稿,因为它可以帮助您更好地使用 MAT 找到问题。

      【讨论】:

        【解决方案4】:

        如果您的应用程序是图像编辑器并且您看到这种类型的行为,那么我希望您没有回收位图内存(请参阅http://developer.android.com/reference/android/graphics/Bitmap.html#recycle%28%29)。

        当你的方向改变并且活动被破坏时,你需要找到你的视图正在使用的任何大型位图,然后在它们上调用recycle 或使用onRetainNonConfigurationInstance 方法(参见http://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance%28%29)传递它到新的 Activity 实例。

        【讨论】:

        • 您好,感谢您的回答,我正在回收 onDestroy() 函数中的每个位图。我正在考虑使用 onRetainNonConfigurationInstance 但这并不能完全解决问题,它只会减轻问题的症状。
        【解决方案5】:

        我的应用程序出现严重泄漏,虽然我发现 MAT 工具很有用,但我发现主要原因是我没有正确管理活动堆栈。我认为检查这一点最有用的方法是从命令行使用:

        adb shell dumpsys meminfo your.package.name

        你会得到类似的输出

        adb shell dumpsys meminfo your.package.name
        Currently running services:
          meminfo
        -------------------------------------------------------------------------------
        DUMP OF SERVICE meminfo:
        Applications Memory Usage (kB):
        Uptime: 150876 Realtime: 150875
        
        ** MEMINFO in pid 253 [your.package.name] **
                            native   dalvik    other    total
                    size:     5404     4103      N/A     9507
               allocated:     5294     3110      N/A     8404
                    free:      101      993      N/A     1094
                   (Pss):     2346     3737     2198     8281
          (shared dirty):     1964     4644     1480     8088
            (priv dirty):     2204     1856      956     5016
        
         Objects
                   Views:       30        ViewRoots:        2
             AppContexts:        3       Activities:        2
                  Assets:        2    AssetManagers:        2
           Local Binders:       13    Proxy Binders:       16
        Death Recipients:        2
         OpenSSL Sockets:        0
        
         SQL
                    heap:        0          dbFiles:        0
               numPagers:        0   inactivePageKB:        0
            activePageKB:        0
        

        检查活动计数并在您更改方向等时观察堆大小的变化。确保您没有开始复制已经运行的活动。您可以使用为启动 Activity 的意图指定的标志来控制堆栈。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-09
          • 2013-04-04
          • 1970-01-01
          • 2017-08-26
          • 2014-08-26
          • 2018-04-07
          相关资源
          最近更新 更多