binder对象回收初探

binder回收初探

 

2018-9-27

IPackageDeleteObserver.Stub继承于Binder类,在应用中进行getPackageManager().deletePackage调用的时候,会传递一个Binder的回调对象给PMS(system_server)

       PackageDeleteObserver observer = new PackageDeleteObserver();

       getPackageManager().deletePackage("com.tencent.mm", observer, 0);

这个试验中,我们的每次点击按钮都会创建一个PackageDeleteObserver对象传给PMS,我们尝试多次点击按钮,new很多对象,看看是否会对系统构成攻击。

为了避免PackageDeleteObserver对象的释放,我们甚至采用ArrayList将其引用起来。

 

public class MainActivity extends Activity

implements OnClickListener {

 

       private static final String TAG = "MyService";

       private List mList = new ArrayList ();

    public class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 

        public void packageDeleted(boolean succeeded) { 

            Log.i(TAG, "======= UNINSTALL_COMPLETE =========="); 

        }

        public void packageDeleted(String s, int i)

        {

              Log.i(TAG, "=======1 UNINSTALL_COMPLETE ==========");

        } 

    } 

      

       public void onClick(View src)

       {

              Log.i(TAG, "onClick: starting service");

             

              PackageDeleteObserver observer = new PackageDeleteObserver();

              mList.add(observer);

              getPackageManager().deletePackage("com.tencent.mm", observer, 0); 

 

Log.i(TAG, "List.size = " + mList.size());

             Log.i(TAG, "onClick: starting service, end of onClick");

       }

      

不断的点击按钮,同时,观察Local Binders的数量

Unknown:/ $ dumpsys meminfo 7365 | grep Binders

       Local Binders:       26        Proxy Binders:       15

Unknown:/ $ dumpsys meminfo 7365 | grep Binders

       Local Binders:       48        Proxy Binders:       15

Unknown:/ $ dumpsys meminfo 7365 | grep Binders

       Local Binders:       55        Proxy Binders:       15

Unknown:/ $ dumpsys meminfo 7365 | grep Binders

       Local Binders:       13        Proxy Binders:       15

 

结果发现,还是被释放了。

why?

 

打开JavaBBinder中的log来观察期创建和析构,

class JavaBBinder : public BBinder

{

public:

    JavaBBinder(JNIEnv* env, jobject object)

        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))

    {

        ALOGD("Creating JavaBBinder %p\n", this);

        android_atomic_inc(&gNumLocalRefs);

        incRefsCreated(env);

    }

 

    virtual ~JavaBBinder()

    {

        ALOGD("Destroying JavaBBinder %p\n", this);

        android_atomic_dec(&gNumLocalRefs);

        JNIEnv* env = javavm_to_jnienv(mVM);

        env->DeleteGlobalRef(mObject);

    }

 

结果发现,JavaBBinder对象确实是可以被释放的,

01-01 17:09:01.784  7365  7365 D JavaBinder: Creating JavaBBinder 0x74a3213080

01-01 17:09:13.376  7365  7378 D JavaBinder: Destroying JavaBBinder 0x74a3213080

 

查看Binder.java中的init方法

    private native final void init();

 

其实现在android_util_Binder.cpp中的

static void android_os_Binder_init(JNIEnv* env, jobject obj)

{

    JavaBBinderHolder* jbh = new JavaBBinderHolder();

    if (jbh == NULL) {

        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);

        return;

    }

    ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);

    jbh->incStrong((void*)android_os_Binder_init);

    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);

}

 

可以看出,Binder对象关联的是JavaBBinderHolder,而不是JavaBBinder对象。

 

当调用端的BinderProxy对象释放的时候,server端的binder对象在没有被引用的情况下也会被释放。

 

你可能感兴趣的:(Android)