请查看以下代码
KeyWordTableCreator.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class KeyWordTableCreator
{
public KeyWordTableCreator(String str)
{
File file = new File(str);
try
{
readAndUpdate(file);
}
catch(IOException io)
{
io.printStackTrace();
}
}
public void readAndUpdate(File file) throws IOException
{
DatabaseConnector db = new DatabaseHandler();
db.makeConnection();
BufferedReader br = new BufferedReader(new FileReader(file));
String str = "";
int index=0;
label1:
while((str=br.readLine())!=null)
{
label2:
for(int i=0;i<str.length();i=i+3)
{
String word = str.substring(i, i+3);
// System.out.println(word);
int insert = db.insert(index, word);
if(insert<0)
{
System.out.println("Operation Broke");
break label1;
}
}
System.out.println("Index Updated: "+index);
//System.out.println(String.valueOf("Total words in this run: "+tempCounter));
index++;
if((index%100)==0)
{
System.gc();
}
}
db.closeConnection();
System.out.println("Completed");
}
}
DatabaseConnector.java
public interface DatabaseConnector {
public void makeConnection();
public void closeConnection();
public int insert(int index, String hashWord);
}
DatabaseHandler.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DatabaseHandler implements DatabaseConnector
{
private Connection con;
@Override
public void makeConnection()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxx","xxx","");
//System.out.println("Connection Established");
}
catch(Exception e)
{
e.printStackTrace();
}
}
@Override
public void closeConnection()
{
try
{
con.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
@Override
public int insert(int index, String hashWord)
{
String str="";
int result=0;
int returnResult=0;
try
{
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("insert into Key_Word (indexVal,hashed_word) values(?,?)");
ps.setInt(1, index);
ps.setString(2, hashWord);
result = ps.executeUpdate();
con.commit();
if(result>0)
{
returnResult = 1;
}
else
{
returnResult = -1;
System.out.println( index+" failed to update");
}
}
catch(SQLException s)
{
returnResult = -1;
s.printStackTrace();
try {
con.rollback();
System.out.println(index+" Exception Occured. Update Failed");
} catch (SQLException ex) {
ex.printStackTrace();
str = index+" Exception Occured. Update Failed. Rollback Failed";
}
}
return returnResult;
}
}
数据库insert()
方法正在KeyWordCreator
内运行。基本上,在其循环内,数据库insert()
方法将被调用1.5亿次。但是,在运行一段时间后,这会给我OutOfMemory Exception
。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.mysql.jdbc.MysqlIO.unpackField(MysqlIO.java:766)
at com.mysql.jdbc.MysqlIO.getResultSet(MysqlIO.java:431)
at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(MysqlIO.java:3245)
at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:2413)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2836)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2828)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2777)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1651)
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3966)
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3943)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java
:2399)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java
:2366)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java
:2350)
at xxx.DatabaseHandler.insert(DatabaseHandler.java:64)
at xxx.KeyWordTableCreator.readAndUpdate(KeyWordTableCreator.ja
va:51)
at xxx.KeyWordTableCreator.<init>(KeyWordTableCreator.java:25)
at xxx.Main.main(Main.java:26)
C:\Users\Dev\Documents\xxx\Key-Word Table Creator\dist>
我该如何解决这个问题?
PS:我已经使用我可以使用的最大内存(java -jar -Xmx1g
)来运行此程序,但这不起作用。
答案 0 :(得分:2)
在执行insert()方法时,请务必调用
ps.close();
result.close();
离开方法之前。否则,所有这些语句和结果集对象都会在内存中构建,直到代码中断为止。
或者,您可以在每个insert()中重用PreparedStatement对象。这不是防止OutOfMemoryError所必需的,但它可能会带来一些执行效率。有关这方面的建议,请参阅Reusing a PreparedStatement multiple times。