首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java java.lang.OutOfMemoryError: Java堆空间

java java.lang.OutOfMemoryError: Java堆空间
EN

Stack Overflow用户
提问于 2013-08-27 09:04:28
回答 3查看 9.8K关注 0票数 0

我开发了一个网络刮刀。Web刮板使用6个线程,每个线程打开一个网页,获取文章的文本,而不是在mysql数据库中写入(使用驱动程序)文本的每个单词。

在程序执行过程中,我得到了一个java java.lang.OutOfMemoryError: Java堆空间。我在Eclipse上安装了内存分析器,发现问题是由mysql驱动程序连接引起的:当我运行这个程序时,5分钟后驱动程序占用的内存为6MB,5分200 MB之后,其余5分500 MB之后,然后得到java错误堆空间。

我不明白为什么会这样。

下面是我为模型使用的代码(用于访问mysql )

代码语言:javascript
复制
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class model {

    private Connection connect = null;

    public model(){
         try {

              Class.forName("com.mysql.jdbc.Driver");
              connect = DriverManager.getConnection("jdbc:mysql://localhost/system?user=keyword_tool&password=l0gripp0");

            } catch (Exception e) {
                System.out.println(e);
            }
    }

    public synchronized void insertCat(String parola, String categoria){

        try{
            PreparedStatement statement = connect.prepareStatement("insert into sostantivi (nome, categoria) values (?, ?)");
            statement.setString(1, parola);
            statement.setString(2, categoria);

            statement.executeUpdate();
            statement.close();

        } catch (Exception e){
            //System.out.println(e);
        }

    }

    public void closeDBConnection() {
        try {
            connect.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

每个线程只需调用方法insertCat并在数据库中插入一个带有类别的单词。

Eclipse的内存分析器插件说:

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-27 09:20:53

根据您的评论,您只创建一个“模型”(这是一个糟糕的类名),并在6个线程中使用它。

这并不是特别好的设计--它的性能要么受到单个DB连接的同步限制(当您可以使用每个线程一个时),要么会遇到潜在的并发问题/错误。

我在堆转储中只看到一个com.mysql.jdbc.JDBC4Connection

这可能是由于错误的显示,或者(理论与你声称的“单一模式”方法相吻合)

理论上,这些应该被缓存和重用--在实践中,你遇到了一个问题。有三个步骤可以尝试:

  1. 更新MySQL驱动程序版本;
  2. 每1000条左右语句关闭并重新打开连接;
  3. 给每个线程自己的连接,或者使用一个连接池。

这看起来像是准备好的语句缓存的某种问题。除非您能够在代码中找到PreparedStmt或ResultSet处理的其他bug (其前景并不明显-- 1)和2),否则最有可能提供解决方案/或特定的解决方案。

票数 2
EN

Stack Overflow用户

发布于 2013-08-27 09:12:57

代码从未关闭到数据库的连接。

尝试在insertCat方法中创建/关闭连接。应尽快获得和释放连接。连接只应在执行持久性操作所需的时间内打开。

代码语言:javascript
复制
public class model {

    public synchronized void insertCat(String parola, String categoria){
        Connection connect = null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            connect = DriverManager.getConnection("jdbc:mysql://localhost/system?user=keyword_tool&password=l0gripp0");
            PreparedStatement statement = connect.prepareStatement("insert into sostantivi (nome, categoria) values (?, ?)");
            statement.setString(1, parola);
            statement.setString(2, categoria);

            statement.executeUpdate();
            statement.close();

        } catch (Exception e){
            //System.out.println(e);
        }finally{
           if(connect != null){
               try {
                  connect.close();
               } catch (Exception e) {
                  System.out.println(e);
               }
           }
        }

    }

}
票数 0
EN

Stack Overflow用户

发布于 2013-08-27 09:17:25

如果您创建新模型而不破坏它,将创建一个新的连接,在您的地图中有2000000模型,所以您将有2000000连接。

应该将所有连接代码提取到连接管理器池中,并由自己管理连接。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18461278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档