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的客户端开发者协助调查。