索引
链接
https://mp.weixin.qq.com/s/huwOkXqfuaALnIg6I6J48A
文章截图
简评
最喜欢这种线上问题分析的文章了,长知识!
这次新知道了一个Java内存分析工具:MAT,memory analyzer tool。还有新知道的知识就是“虚引用”,这种工作中没用过的东西都只存在于当初毕业准备面试时的脑子里。今天看了这个文章之后,专门查了一下虚引用,了解到虚引用是需要PhantomReference来使用的。
Phantom意思是幽灵,PhantomReference也就是虚引用,这个类的构造方法需要传入一个引用以及一个ReferenceQueue,当虚引用对象被回收后,虚引用会被放入指定的ReferenceQueue,此时循环查询ReferenceQueue的代码发现队列中有对象了,就知道对象已经被回收了,然后就可以做一些自定义的操作。例如mysql就在发现虚引用连接对象被回收之后做了关闭网络连接的操作,代码简单解释如下:
public void run() {
//死循环
for (;;) {
try {
checkContextClassLoaders();
//此处使用等待5000毫秒获取一个元素的方式进行循环获取
Reference<? extends ConnectionImpl> ref = NonRegisteringDriver.refQueue.remove(5000);
if (ref != null) {
try {
//获取到了虚引用,就调用虚引用的方法做清理操作
((ConnectionPhantomReference) ref).cleanup();
} finally {
NonRegisteringDriver.connectionPhantomRefs.remove(ref);
}
}
} catch (InterruptedException e) {
threadRef = null;
return;
} catch (Exception ex) {
// Nowhere to really log this.
}
}
}
//下面是ConnectionPhantomReference类定义
static class ConnectionPhantomReference extends PhantomReference<ConnectionImpl> {
private NetworkResources io;
ConnectionPhantomReference(ConnectionImpl connectionImpl, ReferenceQueue<ConnectionImpl> q) {
super(connectionImpl, q);
try {
this.io = connectionImpl.getIO().getNetworkResources();
} catch (SQLException e) {
// if we somehow got here and there's really no i/o, we deal with it later
}
}
//清理方法
void cleanup() {
if (this.io != null) {
try {
this.io.forceClose();
} finally {
this.io = null;
}
}
}
}
原创文章,作者:geekgao,如若转载,请注明出处:https://www.geekgao.cn/archives/1609

微信
支付宝