Java `Android中未知的“(`Other`)内存泄漏?

Java `Android中未知的“(`Other`)内存泄漏?,java,android,memory-leaks,Java,Android,Memory Leaks,Android Studio内存探查器报告其他类别中的分配 根据:其他:系统不确定如何分类的应用程序使用的内存 如果我们深入研究,可以在运行时使用 Android Studio内存分析器中的Others与Debug.MemoryInfo类中的summary.private other相对应。该参数报告为: public int getSummaryPrivateOther() { return getTotalPrivateClean() +

Android Studio内存探查器报告
其他
类别中的分配

根据:其他:系统不确定如何分类的应用程序使用的内存

如果我们深入研究,可以在运行时使用

Android Studio内存分析器中的
Others
Debug.MemoryInfo
类中的
summary.private other
相对应。该参数报告为:

public int getSummaryPrivateOther() {
            return getTotalPrivateClean()
              + getTotalPrivateDirty()
              - getSummaryJavaHeap()
              - getSummaryNativeHeap()
              - getSummaryCode()
              - getSummaryStack()
              - getSummaryGraphics();
        }
哪种内存分配最终属于该类别?它显然不是Java、本机、代码、堆栈和图形

如果我的应用程序(代码库非常大,因此我无法真正确定导致它的特定代码)消耗了大量的
其他
内存,那么是否存在导致这种消耗的特定源/模式

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

哪种内存分配最终属于该类别?它是 显然不是Java、本机、代码、堆栈和图形

RAM信息也可以使用adb shell dumpsys meminfo来检索,通常如下所示:

通过实验,我可以看出,
未知
很可能包含在
私有其他
中。这就引出了下一个问题:
未知
?根据:

系统无法分类为其中一个的任何RAM页 其他更具体的项目。目前,它主要包含本机代码 分配,收集时工具无法识别分配 这些数据是由于地址空间布局随机化(ASLR)造成的。像 Dalvik堆,未知的Pss总数考虑与共享 合子,和私人肮脏是未知的RAM专用于您的应用程序

看起来还是本地分配。可识别的本机分配以
本机
类别结束,但是,由于ASLR,其数据不再可识别的本机分配似乎以
未知
结束

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

如果我的应用程序(有非常大的代码库,所以我不能真的锁定点) 导致它的特定代码)会消耗大量的
其他
内存 是否存在导致此类消费的特定来源/模式?我在寻找答案,比如挂线、打开游标、网络视图等等


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

以下示例代码将导致在HTC One API 19上消耗约100mb的未知内存,在三星Galaxy Note 4(API23)上消耗约120mb的内存,在三星Galaxy S8(API-24)上消耗约94mb的内存:

输出:

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

  • 操作系统是否故意在
    dumpsys meminfo
    中的
    Unknown
    下报告WebView内存,还是它是一个bug?如果它是一个bug,它是否特定于某些操作系统和API级别?如果是故意的,那么使用4-5个活动的
    WebView
    s将使应用程序崩溃,并留下非常混乱的痕迹
  • 对于使用javascript的现代典型网页来说,如此高的内存消耗是正常的,还是存在由某些javascript代码触发的错误?实验上,像
    http://stackoverflow.com/
    占用
    23mb
    。与任何新闻网站一样,用户体验更丰富的页面将占用高达120mb-130mb的空间
  • TLDR:
    WebView
    启用
    Javascript
    是一种常见的使用案例,它会导致某些制造商消耗大量
    未知
    内存。

    更新2018-07-23:与本次调查直接相关的chromium bug tracker存在一个未决问题:


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

    感谢您的调查,这是一个有趣的发现!
        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
        }
    
    while sleep 1; do adb shell dumpsys meminfo com.dkarmazi.memoryleakerapp | grep Unknown; done