7.5.3 finalize函数分析

游标对象被回收前,其finalize函数将被调用。来看CursorWrapperInner的finalize函数,代码如下:

[—>ContentResolver. java:CursorWrapperInner.finalize]


protected void finalize()throws Throwable{

try{

if(mCloseGuard!=null){

mCloseGuard.warnIfOpen();//打印一句警告

}

if(!mProviderReleased&&mContentProvider!=null){

ContentResolver.this.releaseProvider(mContentProvider);

}

//上边这段代码除了打印一句警告外,并没有调用close函数

}finally{

super.finalize();//调用基类的finalize,它会有什么特殊处理吗?

}

}


很可惜,我们寄予厚望的super.finalize函数也不会做出什么特殊的处理。难道Cursor-Window资源就没地方处理了?这个问题的答案如下:

客户端所持有的CursorWindow资源会在该对象执行finalize时被回收。读者可查看CursorWindow的finalize函数。

前面分析过,服务端的close函数由BulkCurosrToCursorAdaptor调用IBulkCursorclose函数触发。但BulkCurosrToCursorAdaptor却没有实现finalize函数,故Bulk-CurosrToCursorAdaptor被回收时,并不会触发服务端的Cursor释放。所以,如客户端不显式调用close,将导致服务端进程的资源无法释放。

提示 笔者在分析Monkey测试失败案例时发现,导致Monkey失败的直接原因是android.process.media进程。根据上下文对finalize的分析可知,问题的根源其实在客户端,当客户端末显示close游标时,将导致android.process.media进程大量资源无法释放直到其最后崩溃。由于使用MediaProvider的客户端较多(包括Music、Gallery3D、Video等),所以每次出现这种问题时,都需要所有MediaProvider的客户端开发者协助调查。