CloseGuard is a mechanism for flagging implicit finalizer cleanup of resources that should have been cleaned up by explicit close methods (aka “explicit termination methods” in Effective Java)
CloseGurad提供了一种机制或者说是一个工具类,用来记录资源泄露的场景,比如使用完的资源(比如cursor/fd)没有正常关闭。
可以参考CloseGuard代码注释中提供的demo为需要管理的对象接入监控。接入之后,如果发生资源使用后没有正常关闭,会在finalize方法中触发CloseGuard的warnIfOpen方法,代码如下:
/*** If CloseGuard is enabled, logs a warning if the caller did not
* properly cleanup by calling an explicit close method
* before finalization. If CloseGuard is disabled, no action is
* performed.
*/
public void warnIfOpen() {
if (allocationSite == null || !ENABLED) {
return;
}
String message =
("A resource was acquired at attached stack trace but never released. "
+ "See java.io.Closeable for information on avoiding resource leaks.");
REPORTER.report(message, allocationSite);
}
APP端可以利用Hook REPORTER 在来实现客制化的上报提示信息。
/**
* Hook for customizing how CloseGuard issues are reported.
*/
private static volatile Reporter REPORTER = new DefaultReporter();
可以参考微信开源的matrix io canary模块,代码如下:
//CloseGuardHooker.java
//通过反射hook了dalvik.system.CloseGuard的成员变量REPORTER,利用动态代理为其设置一个代理对象,
//从而实现客制话
fieldREPORTER.set(null, Proxy.newProxyInstance(classLoader,
new Class<?>[]{closeGuardReporterCls},
new IOCloseLeakDetector(issueListener, sOriginalReporter)));
//IOCloseLeakDetector.java
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MatrixLog.i(TAG, "invoke method: %s", method.getName());
if (method.getName().equals("report")) {
//插入客制化代码
.....
在安卓系统内部已经大量接入了CloseGuard,譬如:
- ActivityView.java (core\java\android\app)
- Animation.java (core\java\android\view\animation)
- ContentProviderClient.java (core\java\android\content)
- ContentResolver.java (core\java\android\content)
- CursorWindow.java (core\java\android\database)
- DisplayEventReceiver.java (core\java\android\view)
- InputEventReceiver.java (core\java\android\view)
- InputQueue.java (core\java\android\view)
- NativeLibraryHelper.java (core\java\com\android\internal\content)
- NetworkStats.java (core\java\android\app\usage)
- PackageManagerService.java (e:\code\android-source\services\core\java\com\android\server\pm)
- ParcelFileDescriptor.java (core\java\android\os)
- PdfDocument.java (e:\code\android-source\graphics\java\android\graphics\pdf)
- PdfEditor.java (e:\code\android-source\graphics\java\android\graphics\pdf)
- PdfRenderer.java (e:\code\android-source\graphics\java\android\graphics\pdf)
- SQLiteConnectionPool.java (core\java\android\database\sqlite)
- SQLiteConnection.java (core\java\android\database\sqlite)
- SQLiteDatabase.java (core\java\android\database\sqlite)
- Surface.java (core\java\android\view)
- SurfaceControl.java (core\java\android\view)
- SystemSensorManager.java (core\java\android\hardware)
- UinputBridge.java (e:\code\android-source\services\core\java\com\android\server\tv)