java - 为什么这个函数会导致内存泄漏?

标签 java mysql memory

public void filterLogins() throws IOException, SQLException{
    for(int i = 0; i<200; ++i){
        BufferedReader bufferedReader = new BufferedReader(new FileReader(folder + String.format("\\data\\part-%05d", i)));
        long prev_id = 0;
        boolean contains = false;
        while(bufferedReader.ready()){ //very big file
            String line = bufferedReader.readLine();
            Login login = new Login(line);
            if ( login.userId == prev_id && !contains )
                continue;
            if ( samples.contains(login.userId) ){
                mysql.execute("INSERT INTO ..."); // i think it doesn't matter in this case
                contains = true;
            }else{
                contains = false;
            }
            prev_id = login.userId;
        }
        bufferedReader.close();
        System.out.println((double)i/2.0);
    }
}

这个函数工作时间长,因为数据是比较大的文件。 2 小时前,这是对 OutOfMemory 异常的迷恋

mysql是

的实例
public class MySQLHandler {
private Connection connection = null;
MySQLHandler() throws ClassNotFoundException, SQLException{
    try{
        Class.forName("com.mysql.jdbc.Driver");
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "root", "");
    }catch (ClassNotFoundException e){
        System.out.println("Failed jdbc driver load.");
        throw e;
    }
}


public void close() throws SQLException{
       if ( connection != null)
           connection.close();
   }
   public boolean execute(String sql) throws SQLException{
       Statement statement = connection.createStatement();
       return statement.execute(sql);
   }
}

登录它只是带有数据的类。 (id, name, value, something else).

最佳答案

看起来,您每次都在创建 Statement 而不是关闭循环中的语句,这会泄漏内存。 执行完成后关闭语句。

 public boolean execute(String sql) throws SQLException{
       Statement statement = connection.createStatement();
       return statement.execute(sql);
   }

喜欢

 public boolean execute(String sql) throws SQLException{
     Statement statement = null;
    try {
        statement = connection.createStatement();
        return statement.execute(sql);
    }finaly{
         if (statement != null) statement.close();
     }

UPDATE

正如@Holger 在评论中提到的,如果您使用的是 JDK 7 及更高版本,那么您可以使用 try-with-resources 如下图

public boolean execute(String sql) throws SQLException{
       try(Statement s=connection.createStatement()) {
          return s.execute(sql);
       }
 }

关于java - 为什么这个函数会导致内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24018928/

相关文章:

java - 如何在 Eclipse(Java 项目)中启用内存监视器?

iphone - 这就是 Objective-C 中垃圾收集的全部内容吗?

java - 从json中获取元素

java - Jersey ResourceFilter 和 spring

javascript - 来自 node-js mysql 连接的错误不会保存到数组

mysql - 如何转换包含货币符号的 varchar 价格列,然后对其求和?

c - 内存布局的.text区域

java - 编译器无法在带有 for、if/else return 语句的方法中找到变量

java - 如何在 Java 中将 ArrayList<ArrayList<String>> 转换为 List<List<String>>?

php - 统计返回的记录 MySQL Doctrine