我开发了一个网络刮刀。Web刮板使用6个线程,每个线程打开一个网页,获取文章的文本,而不是在mysql数据库中写入(使用驱动程序)文本的每个单词。
在程序执行过程中,我得到了一个java java.lang.OutOfMemoryError: Java堆空间。我在Eclipse上安装了内存分析器,发现问题是由mysql驱动程序连接引起的:当我运行这个程序时,5分钟后驱动程序占用的内存为6MB,5分200 MB之后,其余5分500 MB之后,然后得到java错误堆空间。
我不明白为什么会这样。
下面是我为模型使用的代码(用于访问mysql )
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的内存分析器插件说:


发布于 2013-08-27 09:20:53
根据您的评论,您只创建一个“模型”(这是一个糟糕的类名),并在6个线程中使用它。
这并不是特别好的设计--它的性能要么受到单个DB连接的同步限制(当您可以使用每个线程一个时),要么会遇到潜在的并发问题/错误。
我在堆转储中只看到一个com.mysql.jdbc.JDBC4Connection。
这可能是由于错误的显示,或者(理论与你声称的“单一模式”方法相吻合)
理论上,这些应该被缓存和重用--在实践中,你遇到了一个问题。有三个步骤可以尝试:
这看起来像是准备好的语句缓存的某种问题。除非您能够在代码中找到PreparedStmt或ResultSet处理的其他bug (其前景并不明显-- 1)和2),否则最有可能提供解决方案/或特定的解决方案。
发布于 2013-08-27 09:12:57
代码从未关闭到数据库的连接。
尝试在insertCat方法中创建/关闭连接。应尽快获得和释放连接。连接只应在执行持久性操作所需的时间内打开。
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);
}
}
}
}
}发布于 2013-08-27 09:17:25
如果您创建新模型而不破坏它,将创建一个新的连接,在您的地图中有2000000模型,所以您将有2000000连接。
应该将所有连接代码提取到连接管理器池中,并由自己管理连接。
https://stackoverflow.com/questions/18461278
复制相似问题