所属文章:池化技术(一)Druid是如何管理数据库连接的?

本代码段对应流程4.2,防止内存泄漏的连接关闭检测:


//回收长期未归还的连接(再次说明:该方法仅在removeAbandoned设置为true的情况下触发)
public int removeAbandoned() {
int removeCount = 0; long currrentNanos = System.nanoTime(); //这个列表用于存放满足条件的真正需要强制回收的连接
List abandonedList = new ArrayList(); activeConnectionLock.lock();
try {
//在removeAbandoned设置为true的情况下,所有被借出去的连接,都会被保存进activeConnections(参考主流程1),所以要进行“长期未归还”的检查,就是从activeConnections开始的
Iterator iter = activeConnections.keySet().iterator(); for (; iter.hasNext();) {
DruidPooledConnection pooledConnection = iter.next(); if (pooledConnection.isRunning()) {
continue; //如果当前连接正在使用中(指的是正在execute),则不处理
} //利用当前时间和连接被借出去时的时间,计算出连接被借出去的时间有多久
long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000); if (timeMillis >= removeAbandonedTimeoutMillis) { //如果连接被借出去的时间超过removeAbandonedTimeoutMillis这个阈值,将会命中“主动归还”的逻辑检查
iter.remove(); //先从activeConnections移除
pooledConnection.setTraceEnable(false); //标记为false,防止回收时重复removeactiveConnections,可以参考主流程5
abandonedList.add(pooledConnection); //放入“强制回收”队列
}
}
} finally {
activeConnectionLock.unlock();
} if (abandonedList.size() > 0) { //如果“强制回收”队列大于0,说明有需要回收的连接
for (DruidPooledConnection pooledConnection : abandonedList) { //循环这些连接
final ReentrantLock lock = pooledConnection.lock;
lock.lock(); //拿到连接的锁
try {
if (pooledConnection.isDisable()) {
continue; //已经被回收的,则不管
}
} finally {
lock.unlock();
} //触发回收连接对象(pooledConnection)里的holcder(注意这里其实是把pooledConnection对象里的holder给回收至连接池了,pooledConnection对象本身会被销毁)
JdbcUtils.close(pooledConnection); //这里触发的close,是DruidPooledConnection的close,也就是会触发recycle方法的close
pooledConnection.abandond(); //标记为
removeAbandonedCount++;
removeCount++; if (isLogAbandoned()) { //日志打印,忽略
StringBuilder buf = new StringBuilder();
buf.append("abandon connection, owner thread: ");
buf.append(pooledConnection.getOwnerThread().getName());
buf.append(", connected at : ");
buf.append(pooledConnection.getConnectedTimeMillis());
buf.append(", open stackTrace\n"); StackTraceElement[] trace = pooledConnection.getConnectStackTrace();
for (int i = 0; i < trace.length; i++) {
buf.append("\tat ");
buf.append(trace[i].toString());
buf.append("\n");
} buf.append("ownerThread current state is " + pooledConnection.getOwnerThread().getState()
+ ", current stackTrace\n");
trace = pooledConnection.getOwnerThread().getStackTrace();
for (int i = 0; i < trace.length; i++) {
buf.append("\tat ");
buf.append(trace[i].toString());
buf.append("\n");
} LOG.error(buf.toString());
}
}
} return removeCount; //返回本次被强制回收的连接个数
}

Druid-代码段-4-3的更多相关文章

  1. WPF自定义RoutedEvent事件代码段

    今天在写东西的时候,发现常用的代码段里没有RoutedEvent的,因此,写了一个代码段,方便以后使用,顺便记录一下,如何做代码段. 1.在项目中新建一个XML文件,将扩展名修改为snippet. 2 ...

  2. JavaScript代码段整理笔记系列(二)

    上篇介绍了15个常用代码段,本篇将把剩余的15个补齐,希望对大家有所帮助!!! 16.检测Shift.Alt.Ctrl键: event.shiftKey; //检测Shift event.altKey ...

  3. 我们为什么要看《超实用的Node.JS代码段》

    不知道自己Node.JS水平如何?看这张图 如果一半以上的你都不会,必须看这本书,一线工程师用代码和功能页面来告诉你每一个技巧点. 都会一点,但不知道如何检验自己,看看本书提供的面试题: 1.     ...

  4. 《超实用的JavaScript代码段》—— 读后总结

    这本书全是代码,从头到尾跟着坐下来确实收获很多.比那些古板的教科书式的理解更多,不过书中并不是每个例子都做了,有的作者封装的太多,觉得看了收获不多,就没细看——比如模块渐变.有空好好学学这段的代码. ...

  5. Visual Studio常用小技巧一:代码段+快捷键+插件=效率

    用了visual studio 5年多,也该给自己做下备忘录了.每次进新的组换新的电脑,安装自己熟悉的环境又得重新配置,不做些备忘老会忘记一些东西.工具用的好,效率自然翻倍. 1,代码段 在Visua ...

  6. 使用eclipse开发Morphline的Java代码段

    背景:morphline是一个轻量级的etl工具.除了提供标准化的方法之外,还可以定制化的开发java片段.定制化的java片段会在加载时被作为一个独立的类编译,对源数据作处理. morphline关 ...

  7. 前端福利!10个短小却超实用的JavaScript 代码段

    JavaScript正变得越来越流行,它已经成为前端开发的第一选择,并且利用基于JavaScript语言的NodeJS,我们也可以开发出高 性能的后端服务,甚至我还看到在硬件编程领域也出现了JavaS ...

  8. Visual C# 代码段

    代码段是现成的代码段,您可以快速将其插入到您的代码中. 例如,for 代码段创建一个空的 for 循环. 有些代码段为外侧代码段,这些代码段允许您先选择代码行,然后选择要并入选定代码行的代码段. 例如 ...

  9. 十五个常用的jquery代码段【转】

    好的文章顶一个 回到顶部按钮 通过使用 jQuery 中的 animate 和 scrollTop 方法,你无需插件便可创建一个简单地回到顶部动画: 1 // Back to top 2 $('a.t ...

  10. 十五个常用的jquery代码段

    十五个常用的jquery代码段 回到顶部按钮 通过使用 jQuery 中的 animate 和 scrollTop 方法,你无需插件便可创建一个简单地回到顶部动画: 1 // Back to top ...

随机推荐

  1. 第421期 Python 周刊

    新闻 感谢 Guido 链接: https://blog.dropbox.com/topics/company/thank-you--guido Python之父 Guido van Rossum 即 ...

  2. 通过Ajax的访问zuul的跨域问题解决方案

    刚开始在使用jqueryajax跨域请求zuul网关时,在后台发现一直拿不到前台请求的json数据,而前台也一直拿不到后台的响应数据.打开浏览器调试程序发现,本身ajax的POST请求统一都变成了op ...

  3. 3.Python常用逻辑运算符

    #header { /* Initially hidden to prevent FLOUC */ display: none; background-color: #fff; /* Display ...

  4. 大数据环境下mongoDB要加索引

    mongodb在存储大数据时,对查询的字段需要添加索引,我测试的是阿里云30多万的数据量,不加索引查询已经到8秒,而添加索引之后是毫秒级! 为集合加索引 mongodb支持内嵌属性添加索引 db.ag ...

  5. 基于Redis消息的订阅发布应用场景

    目录 基于Redis消息的订阅发布应用场景 1.应用背景 2.困境 2.1 锁表风险 2.2 实时性差 2.3 增加编程复杂性 2.4 实时效果 3.解决方案 3.1 前端传值给服务端 3.2 服务端 ...

  6. document.write() 为什么会清空页面

    很久以前遇到的问题,放着放着就忘记去研究了最近看到一篇文章总结一下作者:abloumeurl:   http://blog.csdn.net/u013451157/article/details/78 ...

  7. 图片切换器(ImageSwitcher)的功能与用法

    ImageSwitcher继承了ViewSwitcher,因此它具有与ViewSwitcher相同的特征:可以在切换View组件时使用动画效果.ImageSwitcher继承了ViewSwitcher ...

  8. [Go] golang中的包管理

    在配置了环境变量$GOPATH后,比如下面这个路径 export GOPATH=/mnt/f/ubuntu/goProject 在这个路径下面会有这几个目录 在src目录下放着我的源码比如: 在同一个 ...

  9. [洛谷P4942][题解]小凯的数字

    这题打着高精的旗号其实是闹着玩的……(我不是题目) 数据范围就是提示你这题O(1)的 我们知道,一个数膜9的余数等于它数字和膜9的余数 我们可以把l到r加起来然后膜9 也就是(l+r)(r-l+1)/ ...

  10. APP自动化针对PO模式进行二次封装之basepage

    APP自动化跟WEB自动化所使用的框架基本一样,都是采用的PO模式结合pytest框架编写自动化测试脚本,为了提高代码的复用性.稳定性和易维护性,我们针对PO模式进行了二次封装,将日志,等待以及异常截 ...