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

2022-09-03 02:55:04

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-otherDebug.MemoryInfo

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

哪种类型的内存分配最终属于该类别?它显然不是Java,Native,Code,Stack和Graphics。

如果我的应用程序(具有非常大的代码库,所以我无法真正确定导致它的某个代码)消耗了大量内存,那么是否有特定的源/模式导致这种消耗?Other

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

哪种类型的内存分配最终属于该类别?它显然不是Java,Native,Code,Stack和Graphics。

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

enter image description here

通过实验,我可以看到它最有可能包含在.这就提出了下一个问题:什么是?根据 https://developer.android.com/studio/command-line/dumpsys.html#meminfoUnknownPrivate OtherUnknown

系统无法分类到其他更具体的项目之一的任何 RAM 页。目前,这主要包含本机分配,由于地址空间布局随机化 (ASLR),工具在收集此数据时无法识别这些分配。与Dalvik堆一样,Pss Total for Unknown考虑了与Zygote的共享,而Private Dirty是仅用于您的应用程序的未知RAM。

看起来它仍然是本机分配。可识别的本机分配最终属于类别,但是,由于 ASLR 而数据不再可识别的本机分配似乎最终位于 。NativeUnknown

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

如果我的应用程序(具有非常大的代码库,所以我无法真正确定导致它的某个代码)消耗了大量内存,那么是否有特定的源/模式导致这种消耗?我正在寻找答案,例如挂线,打开光标,Webview等。Other


答案 1

经过几个小时的研究,我终于发现了一种导致高内存消耗的常见模式:启用 。UnknownWebViewJavascript

以下示例代码将导致HTC One API 19和三星Galaxy Note 4(API23)和三星Galaxy S8(API-24)上的内存消耗:100mbunknown120mb94mb

    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
    }

以下命令将每秒以 kb 类别输出内存):Unknown

while sleep 1; do adb shell dumpsys meminfo com.dkarmazi.memoryleakerapp | grep Unknown; done

输出:

enter image description here

现在,它提出了一系列后续问题,这些问题超出了这个特定问题的范围:

  1. 操作系统是故意报告WebView内存还是一个错误?如果它是一个错误,它是否特定于某些操作系统和API级别?如果是故意的,那么有4-5个活动s将使应用程序崩溃,并带有非常令人困惑的痕迹。Unknowndumpsys meminfoWebView
  2. 对于具有javascript的现代典型网页来说,如此高的内存消耗是正常的,还是存在由某些javascript代码触发的错误?实验上,更简单的网站,如采取.与任何新闻网站一样,具有更丰富用户体验的页面将占用.http://stackoverflow.com/23mb120mb-130mb

TLDR:启用了JavascriptWebView是一个常见的用例,导致在某些制造商上消耗大量未知内存。

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

TL;DR:只有某些版本的WebView(>52)会导致高内存消耗,而较旧的WebViews则很好。原因尚不清楚。


答案 2

推荐