Android中的“未知”(“其他”)内存泄漏?

时间:2017-12-15 20:49:59

标签: java android memory-leaks

Android Studio Memory Profiler报告Others类别中的分配。

enter image description here

根据https://developer.android.com/studio/profile/memory-profiler.html:其他:您的应用使用的内存,系统不确定如何分类。

如果我们深入挖掘,可以使用https://developer.android.com/reference/android/os/Debug.MemoryInfo.html#getMemoryStat(java.lang.String)

在运行时检索类似的内存占用信息

Android Studio Memory Profiler中的Otherssummary.private-other类中的Debug.MemoryInfo相对应。该参数报告为:

public int getSummaryPrivateOther() {
            return getTotalPrivateClean()
              + getTotalPrivateDirty()
              - getSummaryJavaHeap()
              - getSummaryNativeHeap()
              - getSummaryCode()
              - getSummaryStack()
              - getSummaryGraphics();
        }

哪种内存分配最终会出现在该类别中?它显然不是Java,Native,Code,Stack和Graphics。

如果我的应用程序(具有极大的代码库,因此我无法确定某个导致它的特定代码)会占用大量Other内存,是否有某种源/模式导致此类消费

修改1 我能够部分回答第一部分我自己的问题:

  

哪种内存分配最终会出现在该类别中?它是   显然不是Java,Native,Code,Stack和Graphics。

也可以使用adb shell dumpsys meminfo <your proc name>检索RAM信息,通常如下所示:

enter image description here

通过实验,我可以看到Unknown最有可能包含在Private Other中。这提出了下一个问题:什么是Unknown?根据{{​​3}}:

  

系统无法归类为其中一个的任何RAM页面   其他更具体的项目。目前,这主要包含原生   分配,收集时工具无法识别   这个数据归因于地址空间布局随机化(ASLR)。像   Dalvik堆,Pss Total for Unknown考虑了共享   Zygote和Private Dirty是专门用于您的应用程序的未知RAM。

看起来它仍然是原生分配。可识别的本机分配最终在Native类别中,但是,由于ASLR而无法识别其数据的原始分配似乎最终位于Unknown

然而,主要问题仍然存在:

  

如果我的应用程序(具有非常大的代码库,所以我不能真正指出   某个导致它的代码消耗了大量的Other内存,是   有一些导致这种消费的来源/模式?我正在寻找悬挂线程,打开游标,网页浏览等答案。

1 个答案:

答案 0 :(得分:1)

经过数小时的研究,我终于找到了一种导致Unknown内存消耗量高的常见模式:WebView启用了Javascript

以下示例代码将导致在HTC One API 19上大约消耗100mb unknown个内存,在Samsung Galaxy Note 4(API23)上大约消耗120mb以及大约{{1}在三星Galaxy S8(API-24):

94mb

以下命令每秒输出kb类别的 val webView1 = findViewById<WebView>(R.id.webview_1) webView1.settings.javaScriptEnabled = true webView1.webViewClient = WebViewClient() findViewById<Button>(R.id.load_webview_1).setOnClickListener { webView1.loadUrl("http://www.nbcsports.com/") // can be any arbitrary URL } 内存:

Unknown

输出:

enter image description here

现在它提出了一系列跟进问题,这些问题超出了这一特定问题:

  1. 操作系统是否故意在while sleep 1; do adb shell dumpsys meminfo com.dkarmazi.memoryleakerapp | grep Unknown; done Unknown下报告WebView内存,或者它是一个错误?如果它是一个错误,它是否特定于某些操作系统和API级别?如果它是有目的的,那么4-5个活动dumpsys meminfo会使应用程序崩溃,并且会有非常混乱的痕迹。
  2. 现代典型网页的内存消耗是否正常,javascript是否正常,还是某些javascript代码触发了错误?在实验上,像WebView这样的简单网站会占用http://stackoverflow.com/。与任何新闻网站一样,具有更丰富用户体验的网页最多需要23mb
  3. TLDR:启用120mb-130mb的{​​{1}}是一个常见用例,会导致某些制造商消耗大量WebView内存。

    更新2018-07-23:铬虫追踪器有一个与此调查直接相关的未解决问题:https://bugs.chromium.org/p/chromium/issues/detail?id=819901

    TL; DR:只有某些版本的WebView(> 52)会导致较高的内存消耗,而较旧的WebViews则可以。原因仍然不明。

相关问题