MySQL 驱动中虚引用 GC 耗时优化与源码分析

本文要点:
  • 一种优雅解决 MySQL 驱动中虚引用导致 GC 耗时较长问题的解决方法
  • 虚引用的作用与使用场景
  • MySQL 驱动源码中的虚引用分析

背景

​ 在之前文章中写过 MySQL JDBC 驱动中的虚引用导致 JVM GC 耗时较长的问题(可以看这里),在驱动代码(mysql-connector-java 5.1.38版本)中 NonRegisteringDriver 类有个虚引用集合 connectionPhantomRefs 用于存储所有的数据库连接,NonRegisteringDriver.trackConnection 方法负责把新创建的连接放入集合,虚引用随着时间积累越来越多,导致 GC 时处理虚引用的耗时较长,影响了服务的吞吐量:

public ConnectionImpl(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException {
   
	...
	NonRegisteringDriver.trackConnection(this);
  ...
}
public class NonRegisteringDriver implements Driver {
   
  ...
  protected static final ConcurrentHashMap<ConnectionPhantomReference, ConnectionPhantomReference> connectionPhantomRefs = new ConcurrentHashMap();
   
  protected static void trackConnection(com.mysql.jdbc.Connection newConn) {
   
        ConnectionPhantomReference phantomRef = new ConnectionPhantomReference((ConnectionImpl)newConn, refQueue);
        connectionPhantomRefs.put(phantomRef, phantomRef);
    }
  ...
}

​ 尝试减少数据库连接的生成速度,来降低虚引用的数量,但是效果并不理想。最终的解决方案是通过反射获取虚引用集合,利用定时任务来定期清理集合,避免 GC 处理虚引用耗时较长。

// 每两小时清理 connectionPhantomRefs,减少对 mixed GC 的影响
SCHEDULED_EXECUTOR.scheduleAtFixedRate(() -> {
   
  try {
   
    Field connectionPhantomRefs = NonRegisteringDriver.class.getDeclaredField("connectionPhantomRefs");
    connectionPhantomRefs.setAccessible(true);
    Map map = (Map) connectionPhantomRefs.get(NonRegisteringDriver.class);
    if (map.size() > 50) {
   
      map.clear();
    }
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java MySQL驱动源码是指用于连接JavaMySQL数据库的驱动包的源代码。Java MySQL驱动包是由开发者编写的一组类和方法的集合,它提供了与MySQL数据库通信的功能。 Java MySQL驱动包的源码通常包括多个Java类文件,这些类实现了一些接口和抽象类,用于实现与MySQL数据库的交互。源码中的主要类包括:驱动程序管理类(DriverManager)、连接类(Connection)、语句类(Statement)、结果集类(ResultSet)等。 源码中的类和方法通过使用MySQL提供的数据库连接API,与MySQL数据库进行通信。例如,在连接数据库时,驱动程序管理类的getConnection()方法根据给定的URL、用户名和密码建立与数据库的连接。接下来,可以使用连接类的createStatement()方法创建一个语句对象,然后使用该语句对象执行SQL查询或更新语句。执行查询后,可以使用结果集类获取查询结果。 源码中的各个类和方法实现了与MySQL数据库通信所需要的细节,包括建立连接、发送和接收SQL语句、处理数据库事务等。这些源码的实现方式是根据MySQL数据库的通信协议和API规范来完成的。 通过阅读和理解Java MySQL驱动包的源码,我们可以深入了解与MySQL数据库交互的底层细节,并可以根据需要进行二次开发或调试。源码的开放性也为开发者提供了学习和扩展的机会,使得Java MySQL驱动包可以更好地适应不同的应用需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值