You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止或停止Oracle 23 JDBC Driver的Diagnostic.CLOCK线程?

解决Oracle 23 JDBC驱动导致Tomcat关闭时的Diagnostic.CLOCK线程内存泄漏警告

针对Tomcat关闭时出现的oracle.jdbc.diagnostics.Diagnostic.CLOCK线程未停止的内存泄漏警告,提供以下几种可行的解决方法:

  • 禁用JDBC诊断功能
    该线程属于Oracle JDBC诊断模块的定时器线程,直接关闭诊断功能即可避免它被创建。可以通过两种方式设置:

    • 在Tomcat启动参数中添加:-Doracle.jdbc.diagnostics.enabled=false
    • 在应用初始化代码中提前设置系统属性:
      System.setProperty("oracle.jdbc.diagnostics.enabled", "false");
      
  • Web应用销毁时手动清理线程
    编写一个Servlet上下文监听器,在应用销毁时定位该线程并强制停止:

    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import java.lang.reflect.Field;
    import java.util.Timer;
    
    public class OracleJdbcThreadCleanupListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent sce) {}
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
            while (rootGroup.getParent() != null) {
                rootGroup = rootGroup.getParent();
            }
    
            Thread[] threads = new Thread[rootGroup.activeCount()];
            rootGroup.enumerate(threads, true);
    
            for (Thread thread : threads) {
                if (thread != null && "oracle.jdbc.diagnostics.Diagnostic.CLOCK".equals(thread.getName())) {
                    try {
                        // 通过反射获取关联的Timer实例并取消
                        Field timerField = thread.getClass().getDeclaredField("this$0");
                        timerField.setAccessible(true);
                        Timer diagnosticTimer = (Timer) timerField.get(thread);
                        diagnosticTimer.cancel();
                        thread.interrupt();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    随后在web.xml中注册该监听器:

    <listener>
        <listener-class>com.your.package.OracleJdbcThreadCleanupListener</listener-class>
    </listener>
    
  • 升级到最新的Oracle 23c JDBC驱动
    这个问题大概率是Oracle 23c JDBC驱动的已知bug,后续官方发布的补丁版本可能已经修复了线程未正确销毁的问题,建议尝试升级到最新的官方驱动版本。

内容的提问来源于stack exchange,提问作者Awk Omo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:42:37