所属文章:池化技术(一)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. asp.net core 3.0 选项模式1:使用

    本篇只是从应用角度来说明asp.net core的选项模式,下一篇会从源码来分析 1.以前的方式 以前我们使用web.config/app.config时是这样使用配置的 var count = Co ...

  2. React Native-ios环境的搭建

    要在mac系统上搭建RN环境: 一.安装Homebrew.它是一款Mac OS平台下的软件包管理工具. 详见Homebrew的安装这篇文章. 二.安装node和watchman,用Homebrew在命 ...

  3. openshift安装部署

    前置准备工作: 1.每台主机准备好有公钥在 /root/.ssh/authorized_keys,私钥则存放在第一台主机的/root/.ssh/id_rsa 2.确定每台主机的私网IP地址是固定的. ...

  4. IT兄弟连 HTML5教程 使用盒子模型的浮动布局

    虽然使用绝对定位可以实现页面布局,但由于调整某个盒子模型时其他盒子模型的位置并不会跟着改变,所以并不是布局的首选方式.而使用浮动的盒子模型可以向左或向右移动,直到它的外边缘碰到包含它的盒子模型边框或另 ...

  5. mybatis中 == 和 != 的用法

    != 的用法 <if test="xxx != null and xxx !=''"> == 的用法(相较于!=,仅需将双引号和单引号的位置换一下即可) <if ...

  6. asp.net MVC 在Controller控制器中实现验证码输出

    asp.net mvc项目使用到验证码,为了让以前的WebForm代码能利用上代码经过稍微的改动即可使用代码如下: using System; using System.Collections.Gen ...

  7. mysql常用运行原理

    MySQL的客户端/服务器架构 MySQL的服务器程序直接和我们存储的数据打交道,然后可以有好多客户端程序连接到这个服务器程序,发送增删改查的请求,然后服务器就响应这些请求,从而操作它维护的数据.和微 ...

  8. leaflet 结合 Echarts4 实现迁徙图(附源码下载)

    前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...

  9. 【学习笔记】《Java编程思想》 第1~7章

    第一章 对象导论 对整书的概要. 略读. 第二章 一切都是对象 创建一个引用,指向一个对象. 安全的做法:创建一个引用的同时便进行初始化. 对象存储的地方:1)寄存器:这是最快的存储区,因为它位于不同 ...

  10. cf 模拟

    https://codeforces.com/contest/1236/problem/D 题意:一个n*m格子矩阵,放一个人偶在左上角向右走,只能在每个格子最多右转一次,有k个障碍物.求是否能够一次 ...