【发布时间】:2014-11-17 14:52:36
【问题描述】:
我创建了一个 REST 服务,在其中我在运行时加载 JDBC 驱动程序 jar。以下是执行此操作的代码:
Driver driverInstance;
URLClassLoader driverClassLoader;
driverClassLoader = new URLClassLoader (new URL[] { "c:/mysql.jar" }, System.class.getClassLoader());
Class<?> driverClass = driverClassLoader.loadClass("oracle.jdbc.driver.OracleDriver");
Connection conn = driverInstance.connect(connectionString, userDbCredentials);
使用此连接将数据加载到数据库后,我将关闭 连接 和 driverClassLoader 两者。但是在运行了一段时间后,我得到了 java.lang.OutOfMemoryError: PermGen space 在 tomcat 服务器中。
我获取了堆转储,并使用 eclipse Memory Analyzer 打开它,我发现以下泄漏可疑消息: “org.apache.catalina.loader.WebappClassLoader”的13个实例,由“java.net.URLClassLoader @ 0xc155fc10”加载,占用14,083,776(32.21%)字节
我知道这是由于在运行时加载了驱动程序 jar,但我无法找到解决方案。
【问题讨论】:
-
驱动在tomcat的libs/文件夹下吗?
-
不,它是从外部路径读取的。
-
该代码究竟在哪里执行?类加载器的创建是每个驱动程序只创建一次,还是每次调用完成一次?
-
代码在构造函数中执行。我都尝试了,加载一次,每次调用都加载。
-
你知道JDBC drivers don't need to be explicitly loaded anymore吗?如果将 mysql.jar 放在 WEB-INF/lib 或 Tomcat 的库目录中,则可以将所有代码替换为一行:
Connection conn = DriverManager.getConnection(connectionString, userDbCredentials);。取消显式加载驱动程序类可能会解决问题。
标签: java tomcat permgen urlclassloader