------------------------ catalina.2025-06-26.log ------------------------ 26-Jun-2025 11:48:04.128 信息 [Thread-4] org.apache.coyote.AbstractProtocol.pause 暂停ProtocolHandler["http-nio-8080"] 26-Jun-2025 11:48:04.184 信息 [Thread-4] org.apache.catalina.core.StandardService.stopInternal 正在停止服务[Catalina] 26-Jun-2025 11:48:04.246 信息 [Thread-4] org.apache.coyote.AbstractProtocol.stop 正在停止ProtocolHandler ["http-nio-8080"] 26-Jun-2025 11:48:04.251 信息 [Thread-4] org.apache.coyote.AbstractProtocol.destroy 正在摧毁协议处理器 ["http-nio-8080"] 26-Jun-2025 11:48:04.268 警告 [Thread-4] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web应用程序 [KuCun2] 注册了JDBC驱动程序 [com.mysql.cj.jdbc.Driver],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。 26-Jun-2025 11:48:04.276 警告 [Thread-4] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[KuCun2]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[ java.base@11/java.lang.Object.wait(Native Method) java.base@11/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155) com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:91) java.base@11/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) java.base@11/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) java.base@11/java.lang.Thread.run(Thread.java:834)] 26-Jun-2025 11:48:55.666 警告 [main] org.apache.catalina.core.AprLifecycleListener.init 基于APR的本地库加载失败.错误报告为[D:\apache-tomcat-9.0.37\bin\tcnative-1.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform] java.lang.UnsatisfiedLinkError: D:\apache-tomcat-9.0.37\bin\tcnative-1.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method) at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2430) at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2487) at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2684) at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2617) at java.base/java.lang.Runtime.load0(Runtime.java:767) at java.base/java.lang.System.load(System.java:1831) at org.apache.tomcat.jni.Library.<init>(Library.java:42) at org.apache.tomcat.jni.Library.initialize(Library.java:206) at org.apache.catalina.core.AprLifecycleListener.init(AprLifecycleListener.java:198) at org.apache.catalina.core.AprLifecycleListener.isAprAvailable(AprLifecycleListener.java:107) at org.apache.catalina.connector.Connector.<init>(Connector.java:83) at org.apache.catalina.startup.ConnectorCreateRule.begin(ConnectorCreateRule.java:67) at org.apache.tomcat.util.digester.Digester.startElement(Digester.java:1259) at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:510) at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1377) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2708) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824) at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1216) at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:635) at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1517) at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:584) at org.apache.catalina.startup.Catalina.load(Catalina.java:675) at org.apache.catalina.startup.Catalina.load(Catalina.java:712) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:302) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472) 26-Jun-2025 11:48:55.837 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/9.0.37 26-Jun-2025 11:48:55.839 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器构建: Jun 30 2020 20:09:49 UTC 26-Jun-2025 11:48:55.841 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器版本号(: 9.0.37.0 26-Jun-2025 11:48:55.844 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 操作系统名称: Windows 7 26-Jun-2025 11:48:55.846 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.版本: 6.1 26-Jun-2025 11:48:55.847 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 架构: amd64 26-Jun-2025 11:48:55.850 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 环境变量: D:\jdk11_jb51 26-Jun-2025 11:48:55.852 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java虚拟机版本: 11+28 26-Jun-2025 11:48:55.854 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.供应商: Oracle Corporation 26-Jun-2025 11:48:55.856 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: D:\apache-tomcat-9.0.37 26-Jun-2025 11:48:55.858 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: D:\apache-tomcat-9.0.37 26-Jun-2025 11:48:55.861 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:--add-opens=java.base/java.lang=ALL-UNNAMED 26-Jun-2025 11:48:55.864 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:--add-opens=java.base/java.io=ALL-UNNAMED 26-Jun-2025 11:48:55.867 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED 26-Jun-2025 11:48:55.870 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.util.logging.config.file=D:\apache-tomcat-9.0.37\conf\logging.properties 26-Jun-2025 11:48:55.872 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 26-Jun-2025 11:48:55.874 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djdk.tls.ephemeralDHKeySize=2048 26-Jun-2025 11:48:55.876 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.protocol.handler.pkgs=org.apache.catalina.webresources 26-Jun-2025 11:48:55.879 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dignore.endorsed.dirs= 26-Jun-2025 11:48:55.881 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcatalina.base=D:\apache-tomcat-9.0.37 26-Jun-2025 11:48:55.883 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Dcatalina.home=D:\apache-tomcat-9.0.37 26-Jun-2025 11:48:55.885 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数:-Djava.io.tmpdir=D:\apache-tomcat-9.0.37\temp 26-Jun-2025 11:48:56.667 信息 [main] org.apache.coyote.AbstractProtocol.init 初始化协议处理器 ["http-nio-8080"] 26-Jun-2025 11:48:56.844 信息 [main] org.apache.catalina.startup.Catalina.load 服务器在[1446]毫秒内初始化 26-Jun-2025 11:48:56.971 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina] 26-Jun-2025 11:48:56.973 信息 [main] org.apache.catalina.core.StandardEngine.startInternal 正在启动 Servlet 引擎:[Apache Tomcat/9.0.37] 26-Jun-2025 11:48:57.006 信息 [main] org.apache.catalina.startup.HostConfig.deployWAR 正在部署web应用程序存档文件[D:\apache-tomcat-9.0.37\webapps\KuCun2.war] 26-Jun-2025 11:49:01.871 信息 [main] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 26-Jun-2025 11:49:18.187 信息 [main] org.apache.catalina.startup.HostConfig.deployWAR web应用程序存档文件[D:\apache-tomcat-9.0.37\webapps\KuCun2.war]的部署已在[21,180]ms内完成 26-Jun-2025 11:49:18.190 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\apache-tomcat-9.0.37\webapps\docs] 26-Jun-2025 11:49:18.245 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\apache-tomcat-9.0.37\webapps\docs]的部署已在[56]毫秒内完成 26-Jun-2025 11:49:18.247 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\apache-tomcat-9.0.37\webapps\examples] 26-Jun-2025 11:49:18.654 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\apache-tomcat-9.0.37\webapps\examples]的部署已在[407]毫秒内完成 26-Jun-2025 11:49:18.658 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\apache-tomcat-9.0.37\webapps\host-manager] 26-Jun-2025 11:49:18.703 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\apache-tomcat-9.0.37\webapps\host-manager]的部署已在[45]毫秒内完成 26-Jun-2025 11:49:18.709 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\apache-tomcat-9.0.37\webapps\manager] 26-Jun-2025 11:49:18.758 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\apache-tomcat-9.0.37\webapps\manager]的部署已在[50]毫秒内完成 26-Jun-2025 11:49:18.764 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\apache-tomcat-9.0.37\webapps\ROOT] 26-Jun-2025 11:49:18.810 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\apache-tomcat-9.0.37\webapps\ROOT]的部署已在[47]毫秒内完成 26-Jun-2025 11:49:18.820 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄["http-nio-8080"] 26-Jun-2025 11:49:18.845 信息 [main] org.apache.catalina.startup.Catalina.start [22000]毫秒后服务器启动 26-Jun-2025 11:49:56.871 信息 [Thread-4] org.apache.coyote.AbstractProtocol.pause 暂停ProtocolHandler["http-nio-8080"] 26-Jun-2025 11:49:56.912 信息 [Thread-4] org.apache.catalina.core.StandardService.stopInternal 正在停止服务[Catalina] 26-Jun-2025 11:49:57.187 警告 [Thread-4] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[KuCun2]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[ java.base@11/java.lang.Object.wait(Native Method) java.base@11/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155) com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:91) java.base@11/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) java.base@11/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) java.base@11/java.lang.Thread.run(Thread.java:834)] 26-Jun-2025 11:49:57.214 信息 [Thread-4] org.apache.coyote.AbstractProtocol.stop 正在停止ProtocolHandler ["http-nio-8080"] 26-Jun-2025 11:49:57.223 信息 [Thread-4] org.apache.coyote.AbstractProtocol.destroy 正在摧毁协议处理器 ["http-nio-8080"] ------------------------ host-manager.2025-06-26.log ------------------------ ------------------------ localhost.2025-06-26.log ------------------------ 26-Jun-2025 11:48:04.218 信息 [Thread-4] org.apache.catalina.core.ApplicationContext.log SessionListener: contextDestroyed() 26-Jun-2025 11:48:04.218 信息 [Thread-4] org.apache.catalina.core.ApplicationContext.log ContextListener: contextDestroyed() 26-Jun-2025 11:49:02.103 信息 [main] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath 26-Jun-2025 11:49:07.916 信息 [main] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext 26-Jun-2025 11:49:18.643 信息 [main] org.apache.catalina.core.ApplicationContext.log ContextListener: contextInitialized() 26-Jun-2025 11:49:18.644 信息 [main] org.apache.catalina.core.ApplicationContext.log SessionListener: contextInitialized() 26-Jun-2025 11:49:18.646 信息 [main] org.apache.catalina.core.ApplicationContext.log ContextListener: attributeAdded('StockTicker', 'async.Stockticker@13bf8a36') 26-Jun-2025 11:49:56.945 信息 [Thread-4] org.apache.catalina.core.ApplicationContext.log SessionListener: contextDestroyed() 26-Jun-2025 11:49:56.945 信息 [Thread-4] org.apache.catalina.core.ApplicationContext.log ContextListener: contextDestroyed() 26-Jun-2025 11:49:56.970 信息 [Thread-4] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext ------------------------ localhost_access_log.2025-06-26.txt ------------------------ ------------------------ manager.2025-06-26.log ------------------------
时间: 2025-07-28 14:04:05 浏览: 12
<think>根据提供的Tomcat日志,我们主要需要解决两个问题:1.内存泄漏警告:Web应用程序[KuCun2]在停止时未能停止名为[mysql-cj-abandoned-connection-cleanup]的线程,可能导致内存泄漏。2.32位与64位不兼容的警告:加载tcnative-1.dll时出错(Can'tloadIA32-bit.dllonaAMD64-bitplatform)。解决方案如下:问题1:内存泄漏(MySQLJDBC驱动程序线程未停止)原因:MySQLJDBC驱动程序在Web应用程序启动时会启动一个名为"mysql-cj-abandoned-connection-cleanup"的守护线程,用于清理被遗弃的连接。当Web应用程序停止时,Tomcat尝试停止所有由Web应用程序类加载器加载的线程,但这个线程是由驱动程序启动的,且没有被正确停止。解决方案:方法1:在Web应用程序的上下文销毁时,手动停止该线程(推荐)。方法2:升级MySQLJDBC驱动版本(可能已经修复)。方法3:在Tomcat的context.xml中配置<Context>元素,设置JAR扫描规则,避免扫描到驱动程序的JAR,从而让驱动程序由Tomcat的类加载器加载(这样在停止Web应用时不会强制注销驱动)。这里我们使用方法1,在Web应用程序中添加一个ServletContextListener,在contextDestroyed方法中停止该线程。代码示例:创建一个自定义的ServletContextListener:```javapackagecom.example.listener;importjava.lang.reflect.Field;importjava.util.Set;importjava.util.concurrent.ThreadPoolExecutor;importjava.util.concurrent.TimeUnit;importjavax.servlet.ServletContextEvent;importjavax.servlet.ServletContextListener;importjavax.servlet.annotation.WebListener;@WebListenerpublicclassMysqlThreadCleanupListenerimplementsServletContextListener{@OverridepublicvoidcontextInitialized(ServletContextEventsce){//初始化时不需要做任何事}@OverridepublicvoidcontextDestroyed(ServletContextEventsce){shutdownMysqlAbandonedConnectionCleanupThread();}privatevoidshutdownMysqlAbandonedConnectionCleanupThread(){try{//尝试通过反射获取MySQL的清理线程Class<?>cls=Class.forName("com.mysql.cj.jdbc.AbandonedConnectionCleanupThread");//获取静态字段'threadRef'(在较新的驱动中可能是'thread')FieldthreadField=cls.getDeclaredField("thread");threadField.setAccessible(true);Threadthread=(Thread)threadField.get(null);if(thread!=null){thread.interrupt();thread.join(1000);if(thread.isAlive()){//如果线程还在运行,尝试使用ExecutorService的方式关闭Fieldfield=cls.getDeclaredField("executorService");field.setAccessible(true);ThreadPoolExecutorexecutor=(ThreadPoolExecutor)field.get(null);if(executor!=null){executor.shutdown();if(!executor.awaitTermination(1,TimeUnit.SECONDS)){executor.shutdownNow();}}}}//重置线程为nullthreadField.set(null,null);}catch(ClassNotFoundExceptione){//忽略,可能没有使用MySQL驱动}catch(Exceptione){System.err.println("ErrorshuttingdownMySQLAbandonedConnectionCleanupThread:"+e.getMessage());}}}```问题2:32位与64位不兼容原因:Tomcat尝试加载一个32位的本地库(tcnative-1.dll),但运行在64位的JVM上。解决方案:方法1:删除或替换为64位的tcnative-1.dll。方法2:如果不需要APR连接器,可以忽略此警告(不影响Tomcat运行)。步骤:1.确认操作系统是64位,且安装了64位的JDK。2.下载与Tomcat版本对应的64位tcnative-1.dll(可以从ApacheTomcat官网下载,或者从Tomcat的bin目录中删除现有的32位dll文件,然后放入64位dll)。3.或者,直接删除bin目录下的tcnative-1.dll(因为Tomcat默认使用NIO连接器,不需要APR)。操作:删除D:\apache-tomcat-9.0.37\bin\tcnative-1.dll另外,还可以通过配置来禁用APR监听器,在conf/server.xml中注释掉APR相关的连接器(但默认配置中并没有启用APR连接器,所以警告只是来自监听器初始化)。在conf/server.xml中,默认的连接器是NIO,不是APR,所以这个警告可以忽略。但如果想消除警告,可以删除或替换dll文件。综合以上,我们给出两个问题的解决方案。注意:对于内存泄漏问题,我们提供的监听器代码需要添加到Web应用程序(KuCun2)中,并重新打包WAR文件。如果无法修改应用程序,还可以尝试在Tomcat的context.xml中配置:```xml<Context>...<JarScanner><JarScanFilterdefaultPluggabilityScan="false"tldScan="false"/></JarScanner></Context>```但这种方法可能会影响其他功能,不推荐。因此,推荐修改应用程序,添加监听器。下面提供完整的解决方案步骤:步骤1:修改Web应用程序(KuCun2),添加一个ServletContextListener来停止MySQL的清理线程。步骤2:重新打包WAR文件并部署。步骤3:删除Tomcat的bin目录下32位的tcnative-1.dll(或者替换为64位版本)。对于步骤2,如果不想修改应用程序,可以尝试升级MySQLJDBC驱动到最新版本(可能已经修复了线程关闭的问题)。升级驱动:将mysql-connector-java升级到至少8.0.22版本(该版本修复了内存泄漏问题)。因此,另一种方案:方案A:升级驱动(推荐,简单且官方修复)。方案B:添加自定义监听器(如果升级驱动后问题仍存在,再使用)。所以,优先尝试升级MySQL驱动。在pom.xml中更新依赖:```xml<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.27</version><!--使用最新稳定版本--></dependency>```然后重新打包应用。总结:1.升级MySQL驱动到最新版本(8.0.22+)以解决内存泄漏。2.删除或替换Tomcat的bin目录下的tcnative-1.dll文件(32位)为64位版本,或直接删除(因为不需要)。如果升级驱动后仍然出现线程未停止的警告,再考虑添加自定义监听器。最后,提供相关问题的提问。</think>### 解决 Tomcat 日志中的关键问题分析
根据您提供的 Tomcat 日志,我发现了两个主要问题需要解决:内存泄漏警告和 32/64 位兼容性问题。以下是完整的解决方案:
#### 问题1:MySQL JDBC 驱动内存泄漏(关键问题)
**日志警告:**
```
26-Jun-2025 11:49:57.187 警告 [Thread-4] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads
Web应用程序[KuCun2]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。
这很可能会造成内存泄漏。
```
**解决方案:**
1. **在 web.xml 中添加监听器强制关闭线程**:
```xml
<!-- 在 KuCun2 应用的 web.xml 中添加 -->
<listener>
<listener-class>com.mysql.cj.jdbc.AbandonedConnectionCleanupThread</listener-class>
</listener>
```
2. **应用关闭时手动停止线程的 Java 代码**:
```java
package com.yourpackage.util;
import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
public class MysqlCleanupListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// 初始化时不执行任何操作
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// 1. 停止MySQL的废弃连接清理线程
AbandonedConnectionCleanupThread.checkedShutdown();
// 2. 注销JDBC驱动
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
System.out.println("注销JDBC驱动: " + driver.getClass().getName());
} catch (SQLException e) {
System.err.println("注销JDBC驱动失败: " + e.getMessage());
}
}
// 3. 清除线程本地变量
ThreadLocal<?> threadLocal = null;
try {
Class<?> clazz = Class.forName("com.mysql.cj.jdbc.ConnectionImpl");
Field threadLocalField = clazz.getDeclaredField("threadLocalConnectionClosed");
threadLocalField.setAccessible(true);
threadLocal = (ThreadLocal<?>) threadLocalField.get(null);
} catch (Exception e) {
// 忽略反射异常
}
if (threadLocal != null) {
threadLocal.remove();
}
}
}
```
3. **在 web.xml 中注册此监听器**:
```xml
<listener>
<listener-class>com.yourpackage.util.MysqlCleanupListener</listener-class>
</listener>
```
#### 问题2:32/64 位不兼容问题
**日志错误:**
```
26-Jun-2025 11:48:55.666 警告 [main] org.apache.catalina.core.AprLifecycleListener.init
基于APR的本地库加载失败.错误报告为[D:\apache-tomcat-9.0.37\bin\tcnative-1.dll:
Can't load IA 32-bit .dll on a AMD 64-bit platform]
```
**解决方案:**
1. **删除或替换不兼容的 DLL 文件**:
```batch
:: 删除32位dll文件
del /f D:\apache-tomcat-9.0.37\bin\tcnative-1.dll
:: 下载64位版本 (Tomcat 9.0.37)
curl -L -o D:\apache-tomcat-9.0.37\bin\tcnative-1.dll ^
https://archive.apache.org/dist/tomcat/tomcat-connectors/native/1.2.26/binaries/tomcat-native-1.2.26-win64-bin.zip
```
2. **禁用 APR 连接器(如果不使用)**:
```xml
<!-- 修改 conf/server.xml -->
<Listener className="org.apache.catalina.core.AprLifecycleListener"
SSLEngine="off" />
```
3. **验证 JVM 架构一致性**:
```batch
@echo off
set JAVA_HOME=D:\jdk11_jb51
set CATALINA_HOME=D:\apache-tomcat-9.0.37
%JAVA_HOME%\bin\java -version
echo 检查架构一致性...
wmic os get osarchitecture
```
#### 问题3:JAR 扫描警告
**日志信息:**
```
26-Jun-2025 11:49:01.871 信息 [main] org.apache.jasper.servlet.TldScanner.scanJars
至少有一个JAR被扫描用于TLD但尚未包含TLD。
```
**解决方案:**
```xml
<!-- 在 context.xml 中添加 JAR 扫描过滤 -->
<Context>
<JarScanner>
<JarScanFilter
tldScan="*.jar"
tldSkip="bootstrap.jar,tomcat-juli.jar,annotations-api.jar,ecj-*.jar"/>
</JarScanner>
</Context>
```
### 自动诊断和修复脚本
创建 `tomcat_fix.bat` 脚本自动处理问题:
```batch
@echo off
setlocal
set CATALINA_HOME=D:\apache-tomcat-9.0.37
set JAVA_HOME=D:\jdk11_jb51
echo 解决MySQL内存泄漏问题...
echo 创建 MysqlCleanupListener.java...
(
echo package com.yourpackage.util;
echo
echo import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
echo import javax.servlet.ServletContextEvent;
echo import javax.servlet.ServletContextListener;
echo import java.sql.Driver;
echo import java.sql.DriverManager;
echo import java.sql.SQLException;
echo import java.util.Enumeration;
echo import java.lang.reflect.Field;
echo
echo public class MysqlCleanupListener implements ServletContextListener {
echo
echo @Override
echo public void contextInitialized(ServletContextEvent sce) {}
echo
echo @Override
echo public void contextDestroyed(ServletContextEvent sce) {
echo AbandonedConnectionCleanupThread.checkedShutdown();
echo Enumeration<Driver> drivers = DriverManager.getDrivers();
echo while (drivers.hasMoreElements()) {
echo Driver driver = drivers.nextElement();
echo try {
echo DriverManager.deregisterDriver(driver);
echo } catch (SQLException e) { }
echo }
echo try {
echo Class<?> clazz = Class.forName("com.mysql.cj.jdbc.ConnectionImpl");
echo Field threadLocalField = clazz.getDeclaredField("threadLocalConnectionClosed");
echo threadLocalField.setAccessible(true);
echo ThreadLocal<?> threadLocal = (ThreadLocal<?>) threadLocalField.get(null);
echo if (threadLocal != null) threadLocal.remove();
echo } catch (Exception e) { }
echo }
echo }
)> "%CATALINA_HOME%\webapps\KuCun2\WEB-INF\src\com\yourpackage\util\MysqlCleanupListener.java"
echo 更新web.xml...
(
echo ^<listener^>
echo ^<listener-class^>com.yourpackage.util.MysqlCleanupListener^</listener-class^>
echo ^</listener^>
) >> "%CATALINA_HOME%\webapps\KuCun2\WEB-INF\web.xml"
echo 解决32/64位兼容问题...
del /f /q "%CATALINA_HOME%\bin\tcnative-1.dll"
echo 已删除32位tcnative-1.dll
echo 禁用APR监听器(可选)...
findstr /v "AprLifecycleListener" "%CATALINA_HOME%\conf\server.xml" > temp.xml
move /y temp.xml "%CATALINA_HOME%\conf\server.xml"
echo 优化TLD扫描配置...
(
echo ^<Context^>
echo ^<JarScanner^>
echo ^<JarScanFilter
echo tldScan="*.jar"
echo tldSkip="bootstrap.jar,tomcat-juli.jar,annotations-api.jar,ecj-*.jar"/^>
echo ^</JarScanner^>
echo ^</Context^>
) > "%CATALINA_HOME%\conf\context.xml"
echo 清理临时文件...
del /f /q "%CATALINA_HOME%\work\*.*"
del /f /q "%CATALINA_HOME%\temp\*.*"
echo 重启Tomcat服务...
net stop Tomcat9
net start Tomcat9
endlocal
echo 修复完成!
```
### 验证修复效果
1. **检查内存泄漏是否解决**:
- 停止 KuCun2 应用时,日志中不再出现 `mysql-cj-abandoned-connection-cleanup` 警告
2. **验证 64 位兼容性**:
- 启动日志中不再出现 `Can't load IA 32-bit .dll` 错误
3. **检查 TLD 扫描警告**:
- 启动日志中不再出现 `至少有一个JAR被扫描用于TLD但尚未包含TLD` 信息
### 最佳实践建议
1. **定期维护**:
```bat
rem 每月执行清理
del /q /f "%CATALINA_HOME%\logs\*.log"
del /q /f "%CATALINA_HOME%\work\*.*"
```
2. **内存优化**:
```bat
rem 在 catalina.bat 中添加
set JAVA_OPTS=-Xms512m -Xmx2048m -XX:MaxMetaspaceSize=512m
```
3. **连接池配置**:
```xml
<!-- 在 context.xml 中配置 -->
<Resource name="jdbc/YourDB"
auth="Container"
type="javax.sql.DataSource"
maxTotal="100"
maxIdle="30"
maxWaitMillis="10000"
validationQuery="SELECT 1"/>
```
---
###
阅读全文
相关推荐

















