![](/img/trans.png)
[英]JVM's heap size keeps increasing (but usedMemory() keeps decreasing)
[英]JVM heap keeps Increasing. why?
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堆内存使用情况:
为什么我的堆内存不断增加?
如果一个异常被打开后抛出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;
}
您应该使用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;
}
同样,您也不必显式关闭结果集,因为它拥有结果集,所以prepared语句可以这样做:
当
Statement
对象关闭时,其当前ResultSet
对象(如果存在)也将关闭。
但是,如果您想变得偏执并且过分杀伤,正如@MarkRotteveel在其评论中建议的那样,您还可以将ResultSet
添加为AutoCloseable
资源,然后代码如下所示:
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()
) {
...
}
我从来没有做过它,也从来不需要它,文档中明确指出这是没有必要的,但是有些人在某些极端情况下遇到了问题。
在第二种情况下,特别明显的是try-with-resources为您节省了多少费用-您无需将变量分配为null
,不必检查是否已打开任何变量,即使其中一个已打开, close()
方法引发异常,在任何情况下都不会中断“关闭链”,并且会调用其他资源的close()
方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.