Проблема со статическими переменными в Java - PullRequest
3 голосов
/ 30 августа 2011

Я довольно часто использую статические переменные в своем приложении. Теперь, когда статус приложения закончен, я столкнулся с проблемой сбора мусора. Переменные, объявленные как статические, никогда не удаляются сборщиком мусора, и моя память быстро заканчивается.

Конкретная проблема связана с подключением к MySQL. Я храню переменную соединения в статической переменной, поэтому мне не нужно открывать соединение каждый раз, когда я запускаю запрос. Это приводит к проблеме использования всей памяти каждый раз, когда я использую переменную подключения для выполнения запроса, и используемая память не освобождается. Стоит ли хранить переменную соединения в статической переменной? Когда я пытался каждый раз открывать и закрывать соединение без статической переменной, я решал проблему с управлением памятью, но отзывчивость приложения замедлялась в 10-20 раз.

Вам нужно больше информации, чтобы понять эту проблему? Если да, пожалуйста, спросите меня без голосования. Спасибо!

EDIT Это мой разъем класса

import java.sql.*;

public class connect {

    public Connection conn = null;

    public connect() {
        try {
            if (conn == null) {
                String userName = "root";
                String password = "password";               
                String url = "jdbc:mysql://localhost/pos?zeroDateTimeBehavior=convertToNull";                
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                conn = DriverManager.getConnection(url, userName, password);               
                System.out.println("Database connection established");               
            }
        } catch (Exception e) {
            System.err.println("Cannot connect to database server");           
        }
    }
}

Это мой класс, где я храню соединение

public class variables {
    public static connect con = new connect();
}

И этот метод я использую для выполнения запроса

public class mysql_query {
public static ResultSet execute_mysql(Connection con, String sqlStatement) {
        try {
            //ResultSet result = null;
            java.sql.Statement cs = con.createStatement();
            ResultSet result = cs.executeQuery(sqlStatement);
            return result;
        } catch (SQLException ex) {
            Logger.getLogger(mysql_query.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }

    }

 public static void main(String args[]){
     String sql = "SELECT * FROM pos_user_login WHERE moderator='1' AND "
                    + "company_id='1'";

     ResultSet rs = execute_mysql(variables.con.conn, sql);
  }
}

Ответы [ 4 ]

5 голосов
/ 30 августа 2011

Просто идея: Вы, возможно, неправильно закрываете свои ResultSet и Statement объекты. Если вы этого не сделаете, драйвер JDBC MySQL может удерживать многие ресурсы, которые вам больше не нужны. Особенно ResultSet может быть очень болезненным, так как некоторые части курсора базы данных все еще находятся в памяти.

Пример, который может дать вам идею:

PreparedStatement stmt = null;
ResultSet rs = null;

try {
    stmt = connection.prepareStatement(...);
    rs = stmt.executeQuery();
}

// Close your resources in a finally block! Because the finally block
// is executed even if you have exceptions in the try block.
// If you do this a lot of times, write utility methods...
finally {
    try {
        if (rs != null) {
            rs.close();
        }
    } catch (SQLException ignore) {}

    try {
        if (stmt != null) {
            stmt.close();
        }
    } catch (SQLException ignore) {}
}
5 голосов
/ 30 августа 2011

Возможно, было бы лучше взглянуть на использование пула соединений, а не статической переменной ... Пулы соединений поддерживают множество открытых соединений и выдают их, когда они необходимы.Должны решить вашу проблему производительности и проблемы с памятью.

0 голосов
/ 30 августа 2011

Ну, судя по тому, что вы говорите, у вас есть класс объекта (назовем его Obj), который содержит статическую переменную с соединением. Из-за того, что вы каждый раз создаете новый объект Obj и сохраняете его в этот момент, я думаю, что вы делаете много копий соединения, которое JVM не может очистить, потому что они статические.

Вы можете рассмотреть возможность сохранения такого рода информации в классе Model или удалить статическую метку, чтобы JVM могла правильно собирать эти объекты.

0 голосов
/ 30 августа 2011

статическая переменная не будет собирать мусор, но если вы просто храните некоторые данные соединения, это не должно быть проблемой.Что именно вы храните?

Matteo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...