From 6614bb657929c70dad988fb14b4b91f3b9d4f7fc Mon Sep 17 00:00:00 2001 From: Chuanxia Dong Date: Tue, 29 May 2012 12:28:24 +0800 Subject: StorageManager: fix issue that GREF has increased to 2011 in system server with intel stress test. Issue description: When run ICS stress test, always meet GREF issue. one of contributor is MountService$MountServiceBinderListener. log info 19:21:11.609 222 24316 W dalvikvm: 24 of com.android.server.am.ActivityManagerService$AppDeathRecipient (24 unique instances) 19:21:11.609 222 24316 W dalvikvm: 479 of com.android.server.MountService$MountServiceBinderListener (479 unique instances) 19:21:11.619 222 24316 W dalvikvm: 7 of com.android.server.accessibility.AccessibilityManagerService$6 (7 unique instances) Note: PID 222 is system server. Issue alaysis: Everyone can call getSystemService(Context.STORAGE_SERVICE) to get service. When other service get StorageManager, StorageManager will new MountServiceBinderLister and register a listener in MountService, which won't be unregistered. It's easy to generate a lot of instance of unused MountService$MountServiceBinderListener in system server. Issue fix: So change the policy to be: 1. Doesn't new MountServiceBinderLister in construction. 2. when other service needs to register listener in StorageManager, StorageManager will register listener with MountService. 3. When other service needs to unregister listener in StorageManager, if there is no more other listeners in StorageManager, StorageManager will unregister listener in MountService. Change-Id: Iaaf889f44a1a5f62b9f65b3ab1b486c9b7dcaf7f Author: Chuanxiao Dong Signed-off-by: Bo Huang Signed-off-by: Jack Ren Signed-off-by: Bruce Beare --- core/java/android/os/storage/StorageManager.java | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index fbf512c843bb..a4819d8d0706 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -56,7 +56,7 @@ public class StorageManager /* * Our internal MountService binder reference */ - private IMountService mMountService; + final private IMountService mMountService; /* * The looper target for callbacks @@ -304,8 +304,6 @@ public class StorageManager return; } mTgtLooper = tgtLooper; - mBinderListener = new MountServiceBinderListener(); - mMountService.registerListener(mBinderListener); } @@ -322,6 +320,15 @@ public class StorageManager } synchronized (mListeners) { + if (mBinderListener == null ) { + try { + mBinderListener = new MountServiceBinderListener(); + mMountService.registerListener(mBinderListener); + } catch (RemoteException rex) { + Log.e(TAG, "Register mBinderListener failed"); + return; + } + } mListeners.add(new ListenerDelegate(listener)); } } @@ -347,7 +354,15 @@ public class StorageManager break; } } - } + if (mListeners.size() == 0 && mBinderListener != null) { + try { + mMountService.unregisterListener(mBinderListener); + } catch (RemoteException rex) { + Log.e(TAG, "Unregister mBinderListener failed"); + return; + } + } + } } /** -- cgit v1.2.3-59-g8ed1b