簡體   English   中英

java中的靜態變量問題

[英]Problem with static variables in java

我在我的應用程序中使用靜態變量。 現在應用程序狀態完成后,我遇到垃圾收集問題。 聲明為static的變量永遠不會被垃圾收集,我的內存很快耗盡。

具體問題是關於mysql連接。 我將連接變量存儲在靜態變量中,因此每次運行查詢時都不必打開連接。 這導致每次使用連接變量執行查詢時都使用所有內存的問題,並且未釋放使用的內存。 將連接變量存儲在靜態變量中是一個好主意嗎? 當我每次嘗試打開和關閉連接而沒有靜態變量時,我解決了內存管​​理問題,但應用程序的響應速度減慢了10到20倍。

您是否需要更多信息才能理解這個問題? 如果是,請在沒有投票的情況下問我。 謝謝!

編輯這是我的連接器類

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

也許最好是使用連接池而不是靜態變量...連接池維護一堆打開的連接,並在需要時將它們提供出去。 應該解決你的性能問題和你的記憶問題。

只是一個想法:您可能沒有正確關閉ResultSetStatement對象。 如果不這樣做,MySQL JDBC驅動程序可能會保留許多您不再需要的資源。 特別是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) {}
}

靜態變量不會被垃圾收集,但如果你只是存儲一些連接數據,它應該不是問題。 你准確存儲什么?

馬特奧

那么,根據你所說的判斷,你有一個對象(我們稱之為Obj)類,它包含帶有連接的靜態變量。 由於您每次創建一個新的Obj並且您在那時存儲它,我認為您正在做大量的JVM無法清理的連接副本,因為它們是靜態的。

您可以考慮在Model類中存儲此類信息的可能性,或者刪除靜態標記以使JVM正確收集此對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM