Commit 2153a8d7 authored by Dmitry Skiba's avatar Dmitry Skiba Committed by Commit Bot

Overhaul MemoryUma and report pressure from services.

MemoryUma class reports 3 memory pressure related metrics, but there
are issues with them (see the bug), plus metrics are reported only for
the browser process.

We need memory pressure metrics for services too, in order to decide
best ways of handling low memory situations.

This CL deprecates the following metrics:

* MemoryAndroid.NotificationBackground
* MemoryAndroid.NotificationForeground
* MemoryAndroid.LowMemoryTimeBetween

and adds reporting of the following new metrics:

* Android.MemoryPressureNotification.Browser
* Android.MemoryPressureNotification.ChildService

Bug: 834529
Change-Id: If859958ce7adeeb6431f890dea2ffd7a3de8a4f1
Reviewed-on: https://chromium-review.googlesource.com/1013077
Commit-Queue: Dmitry Skiba <dskiba@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarMark Pearson <mpearson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553658}
parent 63246108
......@@ -2796,6 +2796,7 @@ if (is_android) {
"android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java",
"android/java/src/org/chromium/base/memory/MemoryPressureMonitor.java",
"android/java/src/org/chromium/base/memory/MemoryPressureCallback.java",
"android/java/src/org/chromium/base/memory/MemoryPressureUma.java",
]
# New versions of BuildConfig.java and NativeLibraries.java
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.memory;
import android.content.ComponentCallbacks2;
import android.content.res.Configuration;
import android.support.annotation.IntDef;
import org.chromium.base.ContextUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.metrics.RecordHistogram;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Centralizes UMA data collection for Android-specific memory conditions.
*/
public class MemoryPressureUma implements ComponentCallbacks2 {
@IntDef({
Notification.UNKNOWN_TRIM_LEVEL, Notification.TRIM_MEMORY_COMPLETE,
Notification.TRIM_MEMORY_MODERATE, Notification.TRIM_MEMORY_BACKGROUND,
Notification.TRIM_MEMORY_UI_HIDDEN, Notification.TRIM_MEMORY_RUNNING_CRITICAL,
Notification.TRIM_MEMORY_RUNNING_LOW, Notification.TRIM_MEMORY_RUNNING_MODERATE,
Notification.ON_LOW_MEMORY, Notification.NOTIFICATION_MAX,
})
@Retention(RetentionPolicy.SOURCE)
private @interface Notification {
// WARNING: These values are persisted to logs. Entries should not be
// renumbered and numeric values should never be reused.
// Keep in sync with "Android.MemoryPressureNotification" UMA enum.
int UNKNOWN_TRIM_LEVEL = 0;
int TRIM_MEMORY_COMPLETE = 1;
int TRIM_MEMORY_MODERATE = 2;
int TRIM_MEMORY_BACKGROUND = 3;
int TRIM_MEMORY_UI_HIDDEN = 4;
int TRIM_MEMORY_RUNNING_CRITICAL = 5;
int TRIM_MEMORY_RUNNING_LOW = 6;
int TRIM_MEMORY_RUNNING_MODERATE = 7;
int ON_LOW_MEMORY = 8;
// Must be the last one.
int NOTIFICATION_MAX = 9;
}
private final String mHistogramName;
private static MemoryPressureUma sInstance;
public static void initializeForBrowser() {
initializeInstance("Browser");
}
public static void initializeForChildService() {
initializeInstance("ChildService");
}
private static void initializeInstance(String processType) {
ThreadUtils.assertOnUiThread();
assert sInstance == null;
sInstance = new MemoryPressureUma(processType);
ContextUtils.getApplicationContext().registerComponentCallbacks(sInstance);
}
private MemoryPressureUma(String processType) {
mHistogramName = "Android.MemoryPressureNotification." + processType;
}
@Override
public void onLowMemory() {
record(Notification.ON_LOW_MEMORY);
}
@Override
public void onTrimMemory(int level) {
switch (level) {
case TRIM_MEMORY_COMPLETE:
record(Notification.TRIM_MEMORY_COMPLETE);
break;
case TRIM_MEMORY_MODERATE:
record(Notification.TRIM_MEMORY_MODERATE);
break;
case TRIM_MEMORY_BACKGROUND:
record(Notification.TRIM_MEMORY_BACKGROUND);
break;
case TRIM_MEMORY_UI_HIDDEN:
record(Notification.TRIM_MEMORY_UI_HIDDEN);
break;
case TRIM_MEMORY_RUNNING_CRITICAL:
record(Notification.TRIM_MEMORY_RUNNING_CRITICAL);
break;
case TRIM_MEMORY_RUNNING_LOW:
record(Notification.TRIM_MEMORY_RUNNING_LOW);
break;
case TRIM_MEMORY_RUNNING_MODERATE:
record(Notification.TRIM_MEMORY_RUNNING_MODERATE);
break;
default:
record(Notification.UNKNOWN_TRIM_LEVEL);
break;
}
}
@Override
public void onConfigurationChanged(Configuration configuration) {}
private void record(@Notification int notification) {
RecordHistogram.recordEnumeratedHistogram(
mHistogramName, notification, Notification.NOTIFICATION_MAX);
}
}
......@@ -41,7 +41,6 @@ import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.LaunchIntentDispatcher;
import org.chromium.chrome.browser.WarmupManager;
import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer;
import org.chromium.chrome.browser.metrics.MemoryUma;
import org.chromium.chrome.browser.metrics.UmaUtils;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tabmodel.DocumentModeAssassin;
......@@ -75,7 +74,6 @@ public abstract class AsyncInitializationActivity extends AppCompatActivity impl
private Bundle mSavedInstanceState;
private int mCurrentOrientation = Surface.ROTATION_0;
private boolean mDestroyed;
private MemoryUma mMemoryUma;
private long mLastUserInteractionTime;
private boolean mIsTablet;
private boolean mHadWarmStart;
......@@ -217,7 +215,6 @@ public abstract class AsyncInitializationActivity extends AppCompatActivity impl
checkOrientation();
}
});
mMemoryUma = new MemoryUma();
mNativeInitializationController.onNativeInitializationComplete();
}
......@@ -463,7 +460,6 @@ public abstract class AsyncInitializationActivity extends AppCompatActivity impl
@Override
public void onStop() {
super.onStop();
if (mMemoryUma != null) mMemoryUma.onStop();
mNativeInitializationController.onStop();
}
......@@ -583,20 +579,6 @@ public abstract class AsyncInitializationActivity extends AppCompatActivity impl
if (mWindowAndroid != null) mWindowAndroid.saveInstanceState(outState);
}
@CallSuper
@Override
public void onLowMemory() {
super.onLowMemory();
if (mMemoryUma != null) mMemoryUma.onLowMemory();
}
@CallSuper
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (mMemoryUma != null) mMemoryUma.onTrimMemory(level);
}
/**
* @return Whether the activity is running in tablet mode.
*/
......
......@@ -31,6 +31,7 @@ import org.chromium.base.annotations.RemovableInRelease;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.base.memory.MemoryPressureUma;
import org.chromium.chrome.browser.AppHooks;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.ChromeStrictMode;
......@@ -395,6 +396,8 @@ public class ChromeBrowserInitializer {
AsyncTask.THREAD_POOL_EXECUTOR.execute(new LogcatExtractionRunnable(minidump));
}
});
MemoryPressureUma.initializeForBrowser();
}
private ActivityStateListener createActivityStateListener() {
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.metrics;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
import android.os.SystemClock;
import org.chromium.base.metrics.RecordHistogram;
import java.util.concurrent.TimeUnit;
/**
* Centralizes UMA data collection for Android-specific memory conditions.
*/
public class MemoryUma {
// AndroidMemoryNotificationBackground defined in tools/metrics/histograms/histograms.xml.
private static final int BACKGROUND_TRIM_UI_HIDDEN = 0;
private static final int BACKGROUND_TRIM_BACKGROUND = 1;
private static final int BACKGROUND_TRIM_MODERATE = 2;
private static final int BACKGROUND_TRIM_COMPLETE = 3;
private static final int BACKGROUND_MAX = 4;
// AndroidMemoryNotificationForeground defined in tools/metrics/histograms/histograms.xml.
private static final int FOREGROUND_TRIM_MODERATE = 0;
private static final int FOREGROUND_TRIM_LOW = 1;
private static final int FOREGROUND_TRIM_CRITICAL = 2;
private static final int FOREGROUND_LOW = 3;
private static final int FOREGROUND_MAX = 4;
// Timestamp of the last time we received a LowMemory call since Chrome is in foreground.
private long mLastLowMemoryMsec = -1;
public void onStop() {
mLastLowMemoryMsec = -1;
}
public void onLowMemory() {
memoryNotificationForeground(FOREGROUND_LOW);
long now = SystemClock.elapsedRealtime();
if (mLastLowMemoryMsec >= 0) {
RecordHistogram.recordCustomTimesHistogram("MemoryAndroid.LowMemoryTimeBetween",
now - mLastLowMemoryMsec, 0, TimeUnit.MINUTES.toMillis(10),
TimeUnit.MILLISECONDS, 50);
}
mLastLowMemoryMsec = now;
}
public void onTrimMemory(int level) {
if (level >= TRIM_MEMORY_COMPLETE) {
memoryNotificationBackground(BACKGROUND_TRIM_COMPLETE);
} else if (level >= TRIM_MEMORY_MODERATE) {
memoryNotificationBackground(BACKGROUND_TRIM_MODERATE);
} else if (level >= TRIM_MEMORY_BACKGROUND) {
memoryNotificationBackground(BACKGROUND_TRIM_BACKGROUND);
} else if (level >= TRIM_MEMORY_UI_HIDDEN) {
memoryNotificationBackground(BACKGROUND_TRIM_UI_HIDDEN);
} else if (level >= TRIM_MEMORY_RUNNING_CRITICAL) {
memoryNotificationForeground(FOREGROUND_TRIM_CRITICAL);
} else if (level >= TRIM_MEMORY_RUNNING_LOW) {
memoryNotificationForeground(FOREGROUND_TRIM_LOW);
} else if (level >= TRIM_MEMORY_RUNNING_MODERATE) {
memoryNotificationForeground(FOREGROUND_TRIM_MODERATE);
}
}
private static void memoryNotificationForeground(int notification) {
assert notification >= 0 && notification < FOREGROUND_MAX;
RecordHistogram.recordEnumeratedHistogram("MemoryAndroid.NotificationForeground",
notification, FOREGROUND_MAX);
}
private static void memoryNotificationBackground(int notification) {
assert notification >= 0 && notification < BACKGROUND_MAX;
RecordHistogram.recordEnumeratedHistogram("MemoryAndroid.NotificationBackground",
notification, BACKGROUND_MAX);
}
}
......@@ -665,7 +665,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java",
"java/src/org/chromium/chrome/browser/metrics/MediaSessionUMA.java",
"java/src/org/chromium/chrome/browser/metrics/MediaNotificationUma.java",
"java/src/org/chromium/chrome/browser/metrics/MemoryUma.java",
"java/src/org/chromium/chrome/browser/metrics/OneShotImpressionListener.java",
"java/src/org/chromium/chrome/browser/metrics/PackageMetrics.java",
"java/src/org/chromium/chrome/browser/metrics/PageLoadMetrics.java",
......
......@@ -16,6 +16,7 @@ import android.view.Surface;
import org.chromium.base.CommandLine;
import org.chromium.base.JNIUtils;
import org.chromium.base.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.base.UnguessableToken;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
......@@ -23,6 +24,7 @@ import org.chromium.base.annotations.MainDex;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.Linker;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.base.memory.MemoryPressureUma;
import org.chromium.base.process_launcher.ChildProcessServiceDelegate;
import org.chromium.content.browser.ChildProcessCreationParams;
import org.chromium.content.browser.ContentChildProcessConstants;
......@@ -176,6 +178,7 @@ public class ContentChildProcessServiceDelegate implements ChildProcessServiceDe
@Override
public void onBeforeMain() {
nativeInitChildProcess(mCpuCount, mCpuFeatures);
ThreadUtils.postOnUiThread(() -> MemoryPressureUma.initializeForChildService());
}
@Override
......
......@@ -582,6 +582,18 @@ uploading your change for review. These are checked by presubmit scripts.
<int value="5" label="SEARCH"/>
</enum>
<enum name="Android.MemoryPressureNotification">
<int value="0" label="Unknown onTrimMemory() level"/>
<int value="1" label="TRIM_MEMORY_COMPLETE"/>
<int value="2" label="TRIM_MEMORY_MODERATE"/>
<int value="3" label="TRIM_MEMORY_BACKGROUND"/>
<int value="4" label="TRIM_MEMORY_UI_HIDDEN"/>
<int value="5" label="TRIM_MEMORY_RUNNING_CRITICAL"/>
<int value="6" label="TRIM_MEMORY_RUNNING_LOW"/>
<int value="7" label="TRIM_MEMORY_RUNNING_MODERATE"/>
<int value="8" label="onLowMemory()"/>
</enum>
<enum name="AndroidActivityId">
<int value="1" label="Unknown"/>
<int value="2" label="Main"/>
......@@ -923,6 +935,9 @@ uploading your change for review. These are checked by presubmit scripts.
</enum>
<enum name="AndroidMemoryNotificationBackground">
<obsolete>
Deprecated as of 04/2018 (M67).
</obsolete>
<int value="0" label="TrimMemoryUiHidden"/>
<int value="1" label="TrimMemoryBackground"/>
<int value="2" label="TrimMemoryModerate"/>
......@@ -930,6 +945,9 @@ uploading your change for review. These are checked by presubmit scripts.
</enum>
<enum name="AndroidMemoryNotificationForeground">
<obsolete>
Deprecated as of 04/2018 (M67).
</obsolete>
<int value="0" label="TrimMemoryRunningModerate"/>
<int value="1" label="TrimMemoryRunningLow"/>
<int value="2" label="TrimMemoryRunningCritical"/>
......@@ -1387,6 +1387,17 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
<histogram base="true" name="Android.MemoryPressureNotification"
enum="Android.MemoryPressureNotification">
<owner>dskiba@chromium.org</owner>
<summary>
Memory pressure notifications sent by Android through ComponentCallbacks2.
This metric was added 04/2018; for prior data for the browser process see
MemoryAndroid.NotificationBackground and
MemoryAndroid.NotificationForeground.
</summary>
</histogram>
<histogram name="Android.ModerateBindingCount" units="bindings">
<owner>jaekyun@chromium.org</owner>
<summary>
......@@ -41167,6 +41178,9 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</histogram>
<histogram name="MemoryAndroid.LowMemoryTimeBetween" units="ms">
<obsolete>
Deprecated 04/2018.
</obsolete>
<owner>hajimehoshi@chromium.org</owner>
<owner>kenjibaheux@google.com</owner>
<owner>kouhei@chromium.org</owner>
......@@ -41190,6 +41204,9 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
<histogram name="MemoryAndroid.NotificationBackground"
enum="AndroidMemoryNotificationBackground">
<obsolete>
Deprecated 04/2018 in favor of Android.MemoryPressureNotification.
</obsolete>
<owner>hajimehoshi@chromium.org</owner>
<owner>kenjibaheux@google.com</owner>
<owner>kouhei@chromium.org</owner>
......@@ -41201,6 +41218,9 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
<histogram name="MemoryAndroid.NotificationForeground"
enum="AndroidMemoryNotificationForeground">
<obsolete>
Deprecated 04/2018 in favor of Android.MemoryPressureNotification.
</obsolete>
<owner>hajimehoshi@chromium.org</owner>
<owner>kenjibaheux@google.com</owner>
<owner>kouhei@chromium.org</owner>
......@@ -107260,6 +107280,13 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
<affected-histogram name="Signin.AndroidGetAccountsTimeUiThread"/>
</histogram_suffixes>
<histogram_suffixes name="AndroidProcessType" separator=".">
<suffix name="Browser" label="Browser process"/>
<suffix name="ChildService"
label="Child service process (renderer, GPU, etc.)"/>
<affected-histogram name="Android.MemoryPressureNotification"/>
</histogram_suffixes>
<histogram_suffixes name="AndroidTabPersistentStoreTime" separator=".">
<suffix name="CleanupAllEncryptedTime">
<obsolete>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment