返回
用GC监听器检测Android APP GC
Android
2024-01-09 21:20:54
我们用Java弱引用的特性来监听应用是否发生了GC以及GC的频率,Android的源码中也有应用这种技巧。
一、Java中GC的特点
Java中垃圾回收的触发时机是:
- JVM中管理的内存用尽
- 显式调用System.gc()
二、GC原理
GC执行时,JVM中会产生一个临时的大对象,大对象中存放的是即将被回收的对象的引用。GC执行完毕后,GC会释放这个临时对象,临时对象中包含的指向待回收对象引用就会被释放掉。
三、实现原理
Android的源码中,WeakReference实现了java.lang.ref.Reference接口,当与之关联的对象被回收时,WeakReference将会变得不可达,这时通过一个Finalizer的线程,WeakReference会向被观察的对象注册一个死亡引用,当观察对象发生GC时,WeakReference的finalizer方法将会被执行,Finalizer的线程将会触发监听器执行。
四、实现步骤
- 继承WeakReference,并重写Finalizer方法。
- 弱引用中包含我们想要监听的对象。
- 监听器重写onFinalized方法。
public class MyWeakReference extends WeakReference<Context> {
private Object listener;
public MyWeakReference(Context referent, Object listener) {
super(referent);
this.listener = listener;
}
@Override
public void finalize() {
if(listener instanceof FinalizedListener){
((FinalizedListener)listener).onFinalized();
}
}
}
我们通过一个GC监听器实现当发生GC时能够调用的方法。
public class GCListener implements FinalizedListener {
@Override
public void onFinalized() {
Log.i("TAG","GC happened");
}
}
然后我们通过代码来检测发生GC的频率:
public class GCTest {
private Context mContext;
public GCTest(Context context) {
mContext = context;
}
public void start() {
new MyWeakReference(mContext,new GCListener());
mContext = null;
System.gc();
}
}
这个代码中:
- 我们通过weakReference持有Context对象。
- 将Context置为null,然后显式调用System.gc()触发GC。
- 在Finalizer方法中调用GCListener的onFinalized()方法,打印日志。
如果我们的代码执行完毕,说明我们GC监听器能够监听到GC的发生。
五、总结
通过Java弱引用特性以及Finalizer线程,能够监听Android中的GC事件。