[英]Why does this function cause a memory leak?
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,名稱,值等)。
似乎您是在每次創建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);
}
}
嘗試增加JVM的最大堆大小,例如:
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
java -Xms16m -Xmx64m ClassName
還可以優化您的代碼,並在使用后重用變量和關閉/清理。 例如:將它們移出循環:BufferedReader bufferedReader,String行和Login登錄
public void filterLogins() throws IOException, SQLException{
BufferedReader bufferedReader;
long prev_id;
boolean contains;
String line;
Login login;
for(int i = 0; i<200; ++i){
bufferedReader = new BufferedReader(new FileReader(folder + String.format("\\data\\part-%05d", i)));
prev_id = 0;
contains = false;
while(bufferedReader.ready()){ //very big file
line = bufferedReader.readLine();
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.