【发布时间】:2012-02-29 06:09:58
【问题描述】:
在我的应用程序中,我需要在HashMap 或TreeMap 中输入cache 数据,这可以节省大量时间,因为每次从DB server 获取记录并处理它是非常耗时的任务。
我也在使用JProfiler 对此应用程序进行分析,我觉得当我从DataBase 获取记录以放入Map 与ResultSet 的连接时,Statement 没有关闭,因为它正在向我展示这些classes 占用了这么多内存。
这是我对此反应过度还是真的有问题?
顺便说一句,我正在关闭finally block 中的connection。我正在发布它的代码。
public Map someFunction() throws SomeException{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
String sql=null;
Map <String,String> testMap=new TreeMap<String, String>();
try {
con=HMDBUtil.getConnection();
if(cacheSize==0) {
sql = "SELECT SOMETHING FROM SOMEWHERE";
}else {
sql = "SELECT SOMETHING FROM SOMEWHERE_ELSE where rownum<"+cacheSize;
}
stmt=con.createStatement();
stmt.setFetchSize(100000);
rs=stmt.executeQuery(sql);
long count=0;
while(rs.next()) {
testMap.put(rs.getString(1).trim(), rs.getString(2));
count++;
}
} catch (SQLException e) {
log.fatal("SQLException while fetching Data",e);
throw new SomeException("SQLException while fetching Data",e);
}finally {
HMDBUtil.close(con, stmt, rs);
}
return testMap;
}
HMDBUtil.close() 方法---
public static void close(Connection con, Statement stmt, ResultSet rs)
throws SomeException {
if (log.isDebugEnabled())
log.debug("Invoked");
close(rs);
close(stmt);
close(con);
if (log.isDebugEnabled())
log.debug("Leaving");
}
用于关闭所有连接的所有关闭方法 --
public static void close(Connection con) throws SomeException {
try {
if (log.isDebugEnabled())
log.debug("Invoked");
if (con != null) {
con.close();
con = null;
}
if (log.isDebugEnabled())
log.debug("Leaving");
} catch (SQLException e) {
log.fatal("SQLException while Closing connection ", e);
throw new SomeException("SQLException while Closing connection ",
e, false, true);
}
}
public static void close(Statement stmt) throws SomeException {
try {
if (log.isDebugEnabled())
log.debug("Invoked");
if (stmt != null) {
stmt.close();
stmt = null;
}
if (log.isDebugEnabled())
log.debug("Leaving");
} catch (SQLException e) {
// log.error("Exception while Closing statement ", e);
log.fatal("SQLException while Closing statement ", e);
throw new SomeException("SQLException while Closing statement ", e, false, true);
}
}
public static void close(ResultSet rs) throws SomeException {
try {
if (log.isDebugEnabled())
log.debug("Invoked");
if (rs != null) {
rs.close();
rs = null;
}
if (log.isDebugEnabled())
log.debug("Leaving");
} catch (SQLException e) {
log.fatal("SQLException while Closing rs", e);
throw new SomeException("SQLException while Closing rs", e, false, true);
}
}
【问题讨论】:
-
为什么不使用任何缓存 API 以更灵活、更高效的方式为您做到这一点?
-
但问题又是为什么我的分析器显示这些数据库类,即使我已经关闭了它们。
-
你能展示
HMDBUtil.close方法吗? -
@LuiggiMendoza 我已将其发布在问题中
-
是的,它确实有助于垃圾收集器。它可以在方法结束之前计算出它可以收集哪些对象。但是,在您的实现中它不起作用,因为您将 references 设置为 null 以传递给 close 方法的连接和语句。实际对象仍然无法收集,因为它们已在 someFunction 方法中引用。
标签: java performance caching memory jprofiler