Я пытаюсь заполнить JdbcRowSet записями из большой таблицы (около десяти тысяч записей). Я пробовал два варианта (см. код ниже):
- Создайте объект подключения, создайте экземпляр с помощью JdbcRowSetImpl (соединение), выполните запрос в цикле.
- Создайте экземпляр с помощью JdbcRowSetImpl(DriverManager.getConnection("jdbc:...."), выполните запрос в цикле.
Первый вариант приводит к утечке памяти до тех пор, пока куча не будет заполнена. Второй вариант не имеет утечки памяти. Может кто-нибудь объяснить мне, почему первое вызывает утечку памяти при повторном использовании объекта соединения?
Благодарность
Код для 1.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.sql.rowset.JdbcRowSet;
import com.sun.rowset.JdbcRowSetImpl;
public class JdbcRowSetMemoryLeak {
/**
* @param args
*/
public static void main(String[] args) {
String username = "user";
String password = "password";
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost/db_ams?user=" + username + "&password=" + password);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
JdbcRowSet jdbcRS = null;
for (int i=0;i<150;i++){
System.out.println(i);
try {
jdbcRS = new JdbcRowSetImpl(connection); // <-- Memory is leaking
jdbcRS.setCommand("Select * from sample_t;");
jdbcRS.execute();
// jdbcRS.close(); <-- Returns a null pointer Exception
jdbcRS = null;
} catch (SQLException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Код на 2.
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.sql.rowset.JdbcRowSet;
import com.sun.rowset.JdbcRowSetImpl;
public class JdbcRowSetMemoryGood {
/**
* @param args
*/
public static void main(String[] args) {
String username = "user";
String password = "password";
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
JdbcRowSet jdbcRS = null;
for (int i=0;i<150;i++){
System.out.println(i);
try {
jdbcRS = new JdbcRowSetImpl(DriverManager.getConnection("jdbc:mysql://localhost/db_ams?user=" + username + "&password=" + password));
jdbcRS.setCommand("Select * from sample_t;");
jdbcRS.execute();
jdbcRS.close();
jdbcRS = null;
} catch (SQLException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ResultSet
иStatement
(и дажеConnection
, если он объединен) после каждого запроса, вы получите утечку. Как удачно показано здесь.//jdbcRS.close(); <-- Returns a null pointer Exception
. Хм... - person Boris the Spider   schedule 12.09.2013