【发布时间】:2014-08-06 07:55:28
【问题描述】:
我在 NetBeans 中编写了这个简单的类,以了解如何通过 Java 代码连接和管理 Derby 数据库,并使用 IDE 提供的示例数据库作为连接目标。我相信这是一个相当简单的数据库连接示例:
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MainClass {
public static void main(String[] args) {
//Some code that allows me to start the connection only after keyboard input
System.out.println("Program will now connect to database");
try {
System.in.read();
}
catch (IOException ex) {
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
}
// Redirecting DriverManager's output to the console's standard output
DriverManager.setLogWriter(new PrintWriter(System.out));
// This is where I connect to the database, execute a query and print a result
// Still barebones, I am learning SQL basics yet
String dbURL ="jdbc:derby:C:\\users\\project2100\\.netbeans-derby\\sample";
try (Connection conn = DriverManager.getConnection(dbURL, "app", "app")) {
System.out.println("Connected");
try (Statement stmt = conn.createStatement()) {
ResultSet output = stmt.executeQuery("SELECT * FROM CUSTOMER");
while (output.next()) {
System.out.println(output.getString("NAME"));
}
}
}
catch (SQLException ex) {
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
}
// Recently added to keep the application alive
// This way, I can monitor memory usage on Task Manager
try {
System.in.read();
}
catch (IOException ex) {
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Java 的标准输出给了我预期的结果,但DriverManager 的输出告诉我一些我担心的事情;这是应用程序运行的完整控制台输出:
run:
Program will now connect to database
DriverManager.getConnection("jdbc:derby:C:\users\project2100\.netbeans-derby\sample")
trying org.apache.derby.jdbc.AutoloadedDriver40
SQLState(08004) vendor code(40000)
java.sql.SQLException: Connection refused : java.lang.OutOfMemoryError
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.<clinit>(Unknown Source)
at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
at org.apache.derby.jdbc.Driver20.connect(Unknown Source)
at org.apache.derby.jdbc.AutoloadedDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at javadbpg.MainClass.main(MainClass.java:35)
SQLState(08004) vendor code(40000)
java.sql.SQLNonTransientConnectionException: Connection refused : java.lang.OutOfMemoryError
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.<clinit>(Unknown Source)
at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
at org.apache.derby.jdbc.Driver20.connect(Unknown Source)
at org.apache.derby.jdbc.AutoloadedDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at javadbpg.MainClass.main(MainClass.java:35)
Caused by: java.sql.SQLException: Connection refused : java.lang.OutOfMemoryError
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
... 11 more
getConnection returning org.apache.derby.jdbc.AutoloadedDriver40
Connected
Jumbo Eagle Corp
New Enterprises
Wren Computers
Small Bill Company
Bob Hosting Corp.
Early CentralComp
John Valley Computers
Big Network Systems
West Valley Inc.
Zed Motor Co
Big Car Parts
Old Media Productions
Yankee Computer Repair Ltd
BUILD SUCCESSFUL (total time: 23 seconds)
注意:前两个错误之间有 1-2 秒的暂停时间。
就在最近,在 Internet 上查找可能导致这些 OutOfMemoryErrors 的原因后,我添加了最后一个 try 块并观察了应用程序的内存占用。它从最初的 ~9MB 到 ~40MB。
因此,我是否应该在应用程序内部设置一些内存参数,以减少这些错误并最终获得性能? (如果是这样,我可以指点一下吗?)还是应该让所有内容保持原样,让DriverManager 自己工作?
2014-08-07 跟进:
这一次,我在调试模式下运行应用程序,并一步一步记下私有内存的使用情况。兴趣点如下:
- 内存量就在
try (Connection conn = ...语句之前是12MB; - 随后,程序挂起约 5 秒,并触发上述所有
OutOfMemoryErrors; - 5 秒过去后,程序在
System.out.println("Connected");语句之前保留了 37MB 的总内存; -
executeQuery语句又增加了 7MB,总计:45MB。执行时间可以忽略不计(
这是 Bryan Pendleton 要求的 derby.log 文件,它的状态是经过所有先前的测试:
----------------------------------------------------------------
Thu Aug 07 10:10:11 CEST 2014:
Booting Derby version The Apache Software Foundation - Apache Derby - 10.10.1.3 - (1557168): instance a816c00e-0147-af84-a381-0000263f2b92
on database directory C:\Users\Project2100\.netbeans-derby\C3Subjects with class loader sun.misc.Launcher$AppClassLoader@58644d46
Loaded from file:/C:/Program%20Files/Java/jdk1.8.0_05/db/lib/derby.jar
java.vendor=Oracle Corporation
java.runtime.version=1.8.0_05-b13
user.dir=C:\Users\Project2100\Documents\NetBeansProjects\JavaDB Proving Grounds
os.name=Windows 7
os.arch=amd64
os.version=6.1
derby.system.home=C:\users\Project2100\.netbeans-derby
Database Class Loader started - derby.database.classpath=''
昨天我一直在网上搜索内存管理,并尝试使用CLI参数-Xms和-Xns来提高应用程序的启动内存,但无济于事;这些选项仅操作应用程序的保留内存,而最初使用的实际内存通常为 9-10MB。无论如何,我得到相同的内存值、错误和挂起。
我想,现在,我将在loading database... 下记录此行为并继续使用 SQL 本身,因为系统控制台根本没有列出任何投诉。但是,如果确实有办法在数据库连接上抢先分配更多内存,我将不胜感激。
非常感谢您的帮助!
【问题讨论】:
-
`try(ResultSet output = ...´ too.db.apache.org/derby/docs/10.6/ref - search "derby.storage"
-
我会确保该进程至少有 1 GB 或更多。试图节省几 MB 可能是徒劳的。
-
这很奇怪。我不明白发生了什么。我认为我以前从未尝试过像这样窥探 DriverManager 的输出。由于您从查询中获得了正确的输出,显然您已成功建立连接并运行 Derby。您的 derby.log 是什么样的?您是否在 40 MB 实际上代表内存不足的配置中运行?
-
@JoopEggen - 我担心这些存储属性是指存储内存,而我关心的是主要内存使用情况,如果我错了,请纠正我......虽然这解决了我的一些困难数据库 URL 解析 :) @PeterLawrey 我想知道,-Xms 和 -Xns 不能解决问题@Bryan Pendleton 是的,如果我不重定向
DriverManager的输出流,我仍然会完全不知道为什么我的应用程序在连接时挂起 5 秒。我现在用的数据库不强,但我打算做一个视频调度软件;我希望生成的数据库很大。 -
啊,我很抱歉格式不好,似乎 SO 不喜欢换行符。
标签: java memory jdbc out-of-memory derby