executor = Executors.newScheduledThreadPool(1);
Runnable helloRunnable = new Runnable() {
public void run() {
controller2.GetAIntFromDatabase(columblName);
}
};
executor.scheduleAtFixedRate(helloRunnable, 0, 10, TimeUnit.MILLISECONDS);
程序的这一部分会产生不断增加的堆内存错误。
controller2.GetAIntFromDatabase(columblName);
使用此函数我从数据库中读取一个int值。
@Override
public int GetAIntFromDatabase(String columblName) {
int stare = 0;
try{
String query = "SELECT * FROM stari ORDER BY id DESC LIMIT 1";
PreparedStatement preparedStatement = this.connnection.prepareStatement(query);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()){
stare = resultSet.getInt(columblName);
preparedStatement.close();
resultSet.close();
return stare;
}
preparedStatement.close();
resultSet.close();
}catch (SQLException ex) {
System.out.println("GetUtilajStare Error: " + ex);
return 0;
}
return 0;
}
运行10分钟后的Java堆内存使用情况:
为什么我的堆内存不断增加?
答案 0 :(得分:2)
如果在打开preparedStatement
和resultSet
后抛出异常,则永远不会关闭它们。因此,您应该使用始终执行的finally
块。
public int GetAIntFromDatabase(String columblName) {
int stare = 0;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
String query = "SELECT * FROM stari ORDER BY id DESC LIMIT 1";
preparedStatement = this.connnection.prepareStatement(query);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
stare = resultSet.getInt(columblName);
return stare;
}
} catch (SQLException ex) {
System.out.println("GetUtilajStare Error: " + ex);
return 0;
} finally {
if (preparedStatement != null)
preparedStatement.close();
if (resultSet != null)
resultSet.close();
}
return 0;
}
答案 1 :(得分:0)
您应该使用Java 7+关闭资源的方式try-with-resources。
try-with-resources语句是一个声明一个或多个资源的
try
语句。资源是在程序完成后必须关闭的对象。 try-with-resources语句确保在语句结束时关闭每个资源。任何实现AutoCloseable
的对象(包括实现Closeable
的所有对象)都可以用作资源。
public int GetAIntFromDatabase(String columblName) {
final String query = "SELECT * FROM stari ORDER BY id DESC LIMIT 1";
try (final PreparedStatement preparedStatement = this.connnection.prepareStatement(query)) {
final ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return resultSet.getInt(columblName);
}
return 0;
} catch (SQLException ex) {
// Do something better than System.out.println(...)
return 0;
}
return 0;
}
此外,您不必显式关闭结果集,准备好的语句按owns the result set执行:
当
Statement
对象关闭时,其当前ResultSet
对象(如果存在)也将关闭。
然而,如果你想要偏执并且过度杀戮,正如@MarkRotteveel在他的评论中建议的那样,你可以添加AutoCloseable
资源ResultSet
,然后代码看起来像这样:
public int GetAIntFromDatabase(String columblName) {
final String query = "SELECT * FROM stari ORDER BY id DESC LIMIT 1";
try (final PreparedStatement preparedStatement = this.connnection.prepareStatement(query);
final ResultSet resultSet = preparedStatement.executeQuery()
) {
...
}
我从来没有做过,也从不需要它,文档明确指出它不是不是,但有些人在某些边缘情况下遇到了问题。
在第二种情况下,特别可见的是资源试用可以节省多少 - 您无需将变量分配给null
,您无需检查是否有任何变量它们已被打开,即使其中一个close()
方法抛出异常,"关闭链"没有被破坏,并且在任何情况下都会调用其他资源的close()
方法。