简体   繁体   中英

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);

this part of the program generates the increasing heap memory error.

 controller2.GetAIntFromDatabase(columblName); 

with this function I read an int value from my database.

    @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;
    }

That's the Java heap memory usage after 10 minutes of running:

使用Java堆内存10分钟

Why does my heap memory keep increasing?

If an exception is thrown after opening the preparedStatement and the resultSet , they will never be closed. Therefore you should use the finally block which will always be executed.

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;
}

You should use a Java 7+ way of closing the resources, try-with-resources .

The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements AutoCloseable , which includes all objects which implement Closeable , can be used as a resource.

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;
}

Also you do not have to explicitly close the result set, the prepared statement does it as it owns the result set :

When a Statement object is closed, its current ResultSet object, if one exists, is also closed.

However, if you want to be paranoid and overkill it, as @MarkRotteveel suggests in his comment, you may add as an AutoCloseable resource also the ResultSet , and the code would then look like this:

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()
    ) {
    ...
}

I have never done it and never needed it and the documentation explicitly states that it's not necessary, but some people have experienced problems in certain edge cases.

In this second case it's especially visible how much the try-with-resources saves you from - you do not need to assign the variables to null , you do not have to check if any of them have been opened, and even if one of the close() methods throws an exception, the "closing chain" is not broken and the close() methods of the other resources are called in any case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM