2017-12-15 136 views
11

Android Studio Profiler pamięci zgłasza alokacje w kategorii Others."Nieznany" ("Inne") wyciek pamięci w systemie Android?

enter image description here

Według https://developer.android.com/studio/profile/memory-profiler.html: Inny: pamięć używana przez aplikację, że system nie jest pewien, jak zaklasyfikować.

Jeśli będziemy kopać głębiej, podobny ślad pamięci informacje mogą być pobierane w czasie wykonywania przy użyciu https://developer.android.com/reference/android/os/Debug.MemoryInfo.html#getMemoryStat(java.lang.String)

to wygląda Others w Android Studio Memory Profiler odpowiada summary.private-other w Debug.MemoryInfo klasie. Ten parametr jest zgłaszany jako:

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

Jaki rodzaj przydziału pamięci kończy się w tej kategorii? Oczywiście nie jest to Java, Native, Code, Stack i Graphics.

Jeśli moja aplikacja (z ogromnie dużą bazą kodu, więc nie mogę wskazać konkretnego kodu, który ją powoduje) zużywa dużo pamięci Other, czy istnieje pewne źródło/wzorzec, który prowadzi do takiego zużycia?

Edycja 1 Udało mi się częściowo odpowiedzieć na pierwszej części moje własne pytanie:

Jaki rodzaj alokacji pamięci kończy się w tej kategorii? Jest to oczywiście nie Java, Native, Code, Stack i Graphics.

RAM Informacje można również uzyskać za pomocą adb shell dumpsys meminfo <your proc name> i zazwyczaj wygląda następująco:

enter image description here

doświadczalnie, Widzę, że Unknown najprawdopodobniej włączone do Private Other. Co rodzi kolejne pytanie: co to jest Unknown? Według https://developer.android.com/studio/command-line/dumpsys.html#meminfo:

Wszelkie stron RAM, że system nie mógł klasyfikować do jednego z innych bardziej konkretnych przedmiotów. Obecnie zawiera ona głównie natywne przydziały , które nie mogą być zidentyfikowane przez narzędzie podczas zbierania tych danych z powodu Randomizacji Układu Przestrzeni Adresowej (ASLR). Podobnie jak stertę Dalvik z , Pss Total for Unknown bierze pod uwagę współdzielenie z Zygote, a Private Dirty to nieznana pamięć RAM przeznaczona tylko dla twojej aplikacji.

Wygląda na to, że wciąż jest to natywna alokacja. Możliwe do zidentyfikowania alokacje rodzime kończą się w kategorii Native, jednak przydziały macierzyste, których dane nie są już identyfikowalne z powodu ASLR, wydają się kończyć w Unknown.

Podstawowe pytanie jednak nadal posiada:

Jeśli mój app (z ogromnie dużym kodzie więc nie mogę naprawdę punkt pin pewien kod, który go wywołuje) zużywa dużo pamięci Other jest istnieje pewne źródło/wzór, który prowadzi do takiej konsumpcji? Szukam odpowiedzi, takie jak nici wiszące, otwarte kursory, WebViews itp

Odpowiedz

1

Po wielu godzinach badań, jakie w końcu znaleźć jeden wspólny wzór, który prowadzi do wysokiego spożycia Unknown pamięci: WebView z włączonym Javascript .

Następujący kod próbki prowadzi się do spożywania około 100mb z unknown pamięci HTC One API 19 i o 120mb o Samsung Galaxy Uwaga 4 (API23) i około 94mb o Samsung Galaxy S8 (API 24)

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 
    } 

Poniższa komenda wyświetli Unknown pamięci w kB Kategoria co sekundę):

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

wyjściowa:

enter image description here

Teraz rodzi szereg obserwacji pytania, które wykraczają poza tym konkretnym numerze:

  1. Does OS pamięci raport WebView pod Unknown w dumpsys meminfo celowo czy to błąd? Jeśli jest to błąd, czy jest on specyficzny dla niektórych poziomów systemu operacyjnego i interfejsu API? Jeśli jest to celowe, posiadanie 4-5 aktywnych WebView s spowoduje awarię aplikacji z bardzo mylącymi śladami.
  2. Czy jest tak duże zużycie pamięci dla nowoczesnej typowej strony z normalnym javascriptem lub jest też błąd uruchamiany przez pewien kod javascript? Eksperymentalnie prostsze strony, takie jak http://stackoverflow.com/, pobierają 23mb. Strony o bogatszym doświadczeniu, takie jak wszelkie witryny z wiadomościami, zajmą do 120mb-130mb.

TLDR: WebView z włączonym Javascript jeden wspólny przypadek użycia, który prowadzi do spożywania dużo unknown pamięci na niektórych producentów.

+1

Dzięki za dochodzenie, to interesujące znalezisko! – azizbekian