New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 710993 link

Starred by 3 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 3
Type: Bug



Sign in to add a comment

Optimize memory usage of abandoned CCTs

Project Member Reported by dskiba@chromium.org, Apr 12 2017

Issue description

I frequently find myself in a situation where I have several CCTs (opened throught AGSA) in Android's recents, and those CCTs sit there forever just because I forgot to close them.

But those abandoned CCTs are not just entries in recents, they consume very real memory in the browser process. Some of them might even have renderers.

I think we can optimize CCT memory usage on different levels:

1. When CCT is opened in a separate task (AGSA use case), kill renderer for the CCT previously opened by the same app.

2. When CCT is not touched for a long time, either close it (removes from recents), or somehow free most of its memory (keeps the entry in recents).


 

Comment 1 by yus...@chromium.org, Apr 12 2017

Cc: lizeb@chromium.org

Comment 2 by dskiba@chromium.org, Apr 25 2017

Cc: mariakho...@chromium.org
Even though I try hard to always hit back on CCTs from AGSA to close them, apparently sometimes I still forget. Just checked, and found that I have 3 CCTs sitting there, with a single tab opened in Chrome. I only have 2 renderers - one for Chrome's tab, and another is preallocated one, so CCTs don't have their renderers alive.

So I've done a simple experiment: check memory before and after closing CCTs (via chrome://inspect/?tracing#devices).

Before:

** MEMINFO in pid 6571 [com.android.chrome] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap    77111    77076        0        0    65152    74613  4184842
  Dalvik Heap    25915    25828        0        0    54502    39878    14624
 Dalvik Other     1664     1664        0        0
        Stack      800      800        0        0
       Ashmem      544       16        0        0
      Gfx dev     2656     2656        0        0
    Other dev        5        0        4        0
     .so mmap      648      180       16        0
    .apk mmap     9952     1968     5736        0
    .ttf mmap        1        0        0        0
    .dex mmap     4538       12     4252        0
    .oat mmap     1189        0      264        0
    .art mmap     2199     1500      352        0
   Other mmap      921        8      912        0
   EGL mtrack    31488    31488        0        0
      Unknown      332      332        0        0
        TOTAL   159963   143528    11536        0   119654   114491  4199466

 App Summary
                       Pss(KB)
                        ------
           Java Heap:    27680
         Native Heap:    77076
                Code:    12428
               Stack:      800
            Graphics:    34144
       Private Other:     2936
              System:     4899

               TOTAL:   159963      TOTAL SWAP (KB):        0

 Objects
               Views:      616         ViewRootImpl:        4
         AppContexts:       19           Activities:       15
              Assets:        3        AssetManagers:        3
       Local Binders:       82        Proxy Binders:      107
       Parcel memory:       33         Parcel count:      100
    Death Recipients:       26      OpenSSL Sockets:        0


After:

** MEMINFO in pid 6571 [com.android.chrome] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap    73191    73156        0        0    62336    69505  4187134
  Dalvik Heap    24199    24112        0        0    54209    38038    16171
 Dalvik Other     1528     1528        0        0
        Stack      752      752        0        0
       Ashmem      544       16        0        0
      Gfx dev     2656     2656        0        0
    Other dev        5        0        4        0
     .so mmap      648      180       16        0
    .apk mmap     9984     1968     5764        0
    .ttf mmap        1        0        0        0
    .dex mmap     4574       12     4284        0
    .oat mmap     1216        0      272        0
    .art mmap     2199     1500      352        0
   Other mmap      921        8      912        0
   EGL mtrack    31488    31488        0        0
      Unknown      328      328        0        0
        TOTAL   154234   137704    11604        0   116545   107543  4203305

 App Summary
                       Pss(KB)
                        ------
           Java Heap:    25964
         Native Heap:    73156
                Code:    12496
               Stack:      752
            Graphics:    34144
       Private Other:     2796
              System:     4926

               TOTAL:   154234      TOTAL SWAP (KB):        0

 Objects
               Views:      594         ViewRootImpl:        1
         AppContexts:       19           Activities:       15
              Assets:        3        AssetManagers:        3
       Local Binders:       83        Proxy Binders:      106
       Parcel memory:       33         Parcel count:       97
    Death Recipients:       25      OpenSSL Sockets:        0


Few things to note:

1. Number of activities didn't change. Thats because I'm hitting  issue 710612 .

2. Nevertheless, closing these CCTs freed 5.6 MiB private dirty, of which 3.8 MiB came from native.

So, even without renderers stray CCTs affect Chrome's memory usage.

But of course the downside of closing CCTs is that they disappear from Android's recents. Is it possible to replace a CCT activity (that wasn't used for a long time) with a lightweight placeholder just to keep it in recents?

Comment 3 by lizeb@chromium.org, Apr 26 2017

Once the activity leaks are fixed, would this change anything?
Presumably the system will stop / destroy the activities, thus indirectly freeing the native objects that the activity references.

Keeping the current behavior should let the system handle that, right?

Comment 4 by dskiba@chromium.org, Apr 26 2017

Actually, #2 shows even when activities are leaked, closing CCTs reduce memory. I.e. once the leak is fixed (once Chrome on my phone updates) we should see even more dramatic drop in memory per closed CCT.

Comment 5 by lizeb@chromium.org, Apr 26 2017

Sorry, I wasn't clear enough.

The main ways I can see how a Custom Tab activity could increase native memory usage is through holding references to objects, from the framework or Chrome itself. Swiping away the activity probably calls onDestroy(), and resources get freed.
My point is that this should take place naturally, even if another object holds a reference to the activity, onStop() / onDestroy() is probably called anyway.
Wouldn't that be the case?

Comment 6 by dskiba@chromium.org, Apr 26 2017

I need to check that, but I guess you are right, and onDestroy() (but probably not onStop()) frees bunch of objects.

That brings us to the following question: can we force Android to destroy CCT activities (that weren't touched for long), but keep them in recents?

Comment 7 by dskiba@chromium.org, Apr 26 2017

Description: Show this description

Comment 8 by dskiba@chromium.org, Apr 26 2017

Summary: Optimize memory usage of abandoned CCTs (was: Consider killing renderer for the previous CCT)

Comment 9 by lizeb@chromium.org, Apr 26 2017

This seems more of a policy decision than a technical one.
I don't think that removing things from the recent list is a great user experience.
Regarding renderer eviction, is there some precedent for document mode? This seems to be conceptually quite similar.
Hmm, interesting that CCT keeps so much memory alive in the browser process. Would be interesting to understand what it is that stopped CCTs are holding on to.

There's no way to replace anything in recents. But if we could make CCT activity lightweight by getting rid of whatever objects it's holding on to onStop(), that seems like it would be worthwhile?
Labels: android-fe-triaged
Status: Available (was: Untriaged)

Sign in to add a comment