Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1025)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java

Issue 1146813010: Introduce moderate binding (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add "Tab.TotalTabCountBeforeLeavingApp" histogram Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java b/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
index 728699e38e7192555aeca66f39eaa39dfa456517..f080e2e79f76d386928645d0e868e8047e107ecf 100644
--- a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
@@ -4,12 +4,18 @@
package org.chromium.content.browser;
-import android.util.Log;
+import android.content.ComponentCallbacks2;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.util.LruCache;
import android.util.SparseArray;
+import org.chromium.base.ApplicationStatus;
+import org.chromium.base.Log;
import org.chromium.base.SysUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
+import org.chromium.base.metrics.RecordHistogram;
/**
* Manages oom bindings used to bound child services.
@@ -26,6 +32,77 @@ class BindingManagerImpl implements BindingManager {
private final long mRemoveStrongBindingDelay;
private final boolean mIsLowMemoryDevice;
+ private class ModerateBindingPool extends LruCache<Integer, ManagedConnection> {
Yaron 2015/06/11 16:54:34 Can this be static?
Jaekyun Seok (inactive) 2015/06/12 06:50:20 Done.
+ public ModerateBindingPool(
+ Context context, final float lowReduceRatio, final float highReduceRatio) {
+ super(ChildProcessLauncher.getNumberOfServices(context, true));
+
+ context.registerComponentCallbacks(new ComponentCallbacks2() {
+ @Override
+ public void onTrimMemory(int level) {
+ Log.i(TAG, "onTrimMemory: level=" + level + ", size=" + size());
+ if (size() > 0) {
+ if (level <= TRIM_MEMORY_RUNNING_MODERATE) {
+ reduce(lowReduceRatio);
+ } else if (level <= TRIM_MEMORY_RUNNING_LOW) {
+ reduce(highReduceRatio);
+ } else {
+ evictAll();
+ }
+ }
+ }
+
+ @Override
+ public void onLowMemory() {
+ Log.i(TAG, "onLowMemory: evict " + size() + " bindings");
+ evictAll();
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration configuration) {}
+ });
+ }
+
+ private void reduce(float reduceRatio) {
+ int newSize = (int) (size() * (1f - reduceRatio));
+ Log.i(TAG, "Reduce connections from " + size() + " to " + newSize);
+ if (newSize == 0) {
+ evictAll();
+ } else {
+ trimToSize(newSize);
+ }
+ }
+
+ void addConnection(ManagedConnection managedConnection) {
+ ChildProcessConnection connection = managedConnection.mConnection;
+ if (connection != null && connection.isInSandbox()) {
+ managedConnection.addModerateBinding();
+ if (connection.isModerateBindingBound()) {
+ put(connection.getServiceNumber(), managedConnection);
+ } else {
+ remove(connection.getServiceNumber());
+ }
+ }
+ }
+
+ void removeConnection(ManagedConnection managedConnection) {
+ ChildProcessConnection connection = managedConnection.mConnection;
+ if (connection != null && connection.isInSandbox()) {
+ remove(connection.getServiceNumber());
+ }
+ }
+
+ @Override
+ protected void entryRemoved(boolean evicted, Integer key, ManagedConnection oldValue,
+ ManagedConnection newValue) {
+ if (oldValue != newValue) {
+ oldValue.removeModerateBinding();
+ }
+ }
+ }
+
+ private ModerateBindingPool mModerateBindingPool;
+
/**
* Wraps ChildProcessConnection keeping track of additional information needed to manage the
* bindings of the connection. The reference to ChildProcessConnection is cleared when the
@@ -59,10 +136,13 @@ class BindingManagerImpl implements BindingManager {
if (connection == null) return;
connection.addStrongBinding();
+ if (mModerateBindingPool != null) {
+ mModerateBindingPool.removeConnection(this);
+ }
}
/** Removes a strong service binding. */
- private void removeStrongBinding() {
+ private void removeStrongBinding(final boolean keepsAsModerate) {
final ChildProcessConnection connection = mConnection;
// We have to fail gracefully if the strong binding is not present, as on low-end the
// binding could have been removed by dropOomBindings() when a new service was started.
@@ -75,6 +155,10 @@ class BindingManagerImpl implements BindingManager {
public void run() {
if (connection.isStrongBindingBound()) {
connection.removeStrongBinding();
+ if (mModerateBindingPool != null && !connection.isStrongBindingBound()
Yaron 2015/06/11 16:54:34 Shouldn't this be !connection.isModerateBindingBou
Jaekyun Seok (inactive) 2015/06/12 06:50:20 This is to confirm whether a strong binding is act
+ && keepsAsModerate) {
+ mModerateBindingPool.addConnection(ManagedConnection.this);
+ }
}
}
};
@@ -86,6 +170,20 @@ class BindingManagerImpl implements BindingManager {
}
}
+ /** Removes the moderate service binding. */
+ private void removeModerateBinding() {
+ if (mConnection == null || !mConnection.isModerateBindingBound()) return;
+ mConnection.removeModerateBinding();
+ }
+
+ /** Adds the moderate service binding. */
+ private void addModerateBinding() {
+ ChildProcessConnection connection = mConnection;
+ if (connection == null) return;
+
+ connection.addModerateBinding();
+ }
+
/**
* Drops the service bindings. This is used on low-end to drop bindings of the current
* service when a new one is used in foreground.
@@ -109,7 +207,7 @@ class BindingManagerImpl implements BindingManager {
if (!mInForeground && nextInForeground) {
addStrongBinding();
} else if (mInForeground && !nextInForeground) {
- removeStrongBinding();
+ removeStrongBinding(true);
}
mInForeground = nextInForeground;
@@ -130,7 +228,7 @@ class BindingManagerImpl implements BindingManager {
if (!mBoundForBackgroundPeriod && nextBound) {
addStrongBinding();
} else if (mBoundForBackgroundPeriod && !nextBound) {
- removeStrongBinding();
+ removeStrongBinding(false);
}
mBoundForBackgroundPeriod = nextBound;
@@ -146,6 +244,9 @@ class BindingManagerImpl implements BindingManager {
void clearConnection() {
mWasOomProtected = mConnection.isOomProtectedOrWasWhenDied();
+ if (mModerateBindingPool != null) {
+ mModerateBindingPool.removeConnection(this);
+ }
mConnection = null;
}
@@ -256,6 +357,12 @@ class BindingManagerImpl implements BindingManager {
mBoundForBackgroundPeriod = mLastInForeground;
}
}
+ if (mModerateBindingPool != null) {
+ Log.i(TAG, "Release moderate connections: " + mModerateBindingPool.size());
+ RecordHistogram.recordCountHistogram(
+ "MobileBindingManager.ModerateBindingCount", mModerateBindingPool.size());
+ mModerateBindingPool.evictAll();
+ }
}
@Override
@@ -294,4 +401,13 @@ class BindingManagerImpl implements BindingManager {
return mManagedConnections.get(pid).isConnectionCleared();
}
}
+
+ @Override
+ public void startModerateBinding(float lowReduceRatio, float highReduceRatio) {
+ if (mIsLowMemoryDevice || mModerateBindingPool != null) return;
+
+ Log.i(TAG, "Moderate binding enabled: " + lowReduceRatio + " " + highReduceRatio);
+ mModerateBindingPool = new ModerateBindingPool(
+ ApplicationStatus.getApplicationContext(), lowReduceRatio, highReduceRatio);
+ }
}

Powered by Google App Engine
This is Rietveld 408576698