java中静态变量的问题

发布于 2024-12-02 02:07:07 字数 1972 浏览 0 评论 0原文

我在我的应用程序中大量使用静态变量。现在,应用程序状态完成后,我面临垃圾收集的问题。声明为静态的变量永远不会被垃圾回收,并且我的内存很快就会耗尽。

具体问题出在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);
  }
}

I am using static variables pretty much heavily in my application. Now after the application status is finished I am facing a problem in garbage collection. The variables that are declares as static are never garbage collected and my memory runs out quickly.

The specific problem is on mysql connection. I am storing the connection variable in a static variable and so I don't have to open the connection every time I run a query. This leads to a problem of usage of all memory every time I use the connection variable to execute the query and the used memory is not released. Is it a good idea to store the connection variable in static variable ? when I tried to open and close the connection every time without static variable I solved the memory management problem but the responsiveness of the application is slowed down by 10 to 20 times.

Do you need more information to understand this problem ? If yes please ask me without down voting. Thanks!

EDIT
This is my connector class

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

This is my class where i am storing the connection

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

And this method i use to execute the query

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

俏︾媚 2024-12-09 02:07:07

只是一个想法:您可能没有正确关闭 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) {}
}

Just an idea: You might not be closing your ResultSet and Statement objects, correctly. If you don't do that, the MySQL JDBC driver might keep a hold on many resources that you don't need anymore. Especially ResultSet can be very painful, as some parts of the database cursor are still in memory.

An example to give you an idea is this:

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) {}
}
口干舌燥 2024-12-09 02:07:07

也许最好考虑使用连接池而不是静态变量...连接池维护一堆打开的连接并在需要时提供它们。应该解决你的性能问题和内存问题。

Maybe it'd be better to look at using a connection pool rather than the static variable... Connection pools maintain a bunch of open connections and serve them out when they're needed. Should solve your performance problem and your memory problem.

爱你不解释 2024-12-09 02:07:07

静态变量不会被垃圾收集,但如果您只是存储一些连接数据,那么它应该不是问题。你到底在存储什么?

马泰奥

a static variable will not garbage collected but if you are just storing a some connection data it should not be a problem. What are you exactly storing?

Matteo

浊酒尽余欢 2024-12-09 02:07:07

好吧,根据您所说的判断,您有一个对象(我们称之为 Obj)类,其中包含具有连接的静态变量。由于您每次创建一个新的 Obj 并在此时存储它,我认为您正在制作大量连接副本,JVM 无法清理这些副本,因为它们是静态的。

您可以考虑将此类信息存储在 Model 类中,或者删除静态标记以便让 JVM 正确收集此类对象。

Well, judging by what you say, you have an object (let's call it Obj) class which contains the static variable with the connection. Due to you creates a new Obj each time and you stores it at that moment, I think you are doing a lot of copies of the connection which the JVM is unable to clean because they are static.

You could consider the possibility of store this kind of information in a Model class, or remove the static mark in order to let the JVM collect this objects properly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文