1
在Glassfish上長時間運行的後臺進程中,我遇到了OutOfMemoryError
。內存分析表明,在錯誤發生時,50%的堆專用於com.mysql.JDBC4ResultSet
(28.1%)和com.mysql.jdbc.StatementImpl
(22.1%)的實例。Glassfish上的JDBC緩存
我的代碼的結構是假設我的JDBC對象一旦鬆動範圍就會被垃圾收集,但顯然不是這種情況。我原本是使用JPA做的,但是內存負載爆炸了,所以我恢復到了JDBC,但是我仍然收到巨大的內存泄漏,其中包含對JDBC語句& ResultSets的引用。
所以我想知道如果Glassfish緩存這些查詢,我怎麼可以禁用,數據對象是相當大的,我真的不需要它們被緩存。
我在下面包含了我的代碼的結構,它由一個類和兩個方法組成(爲了簡潔而修改)。
@Stateless
public class WSDFileCollector implements Collector {
@PersistenceContext
private EntityManager em;
@Override
@Asynchronous
public void run(final CollectorEntity collector) throws SQLException {
final Connection connection = em.unwrap(Connection.class);
final String table = "tmp_sat_" + collector.getSite().getId();
final String column = "filename";
try {
// Create temporary table
// Scan files & folders under a given directory.
// Load filenames into MySQL Temporary table.
final Statement statement = connection.createStatement();
final ResultSet results = statement.executeQuery("SELECT filename FROM temporary_table WHERE filename NOT IN (SELECT filename FROM existing_files");
while (results.next()) {
final File file = new File(collector.getPath(), results.getString("filename"));
if (file.isFile()) {
extractAndSave(file, collector);
}
}
} finally {
// Delete temporary table
}
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void extractAndSave(final File file, final CollectorEntity collector) {
final Connection connection = em.unwrap(Connection.class);
try {
// Begin a transaction
// INSERT new file into existing_files
// Scan the file, extract data and insert into multiple database tables.
// Commit transaction
} catch (final SQLException | FileNotFoundException ex) {
// Rollback transaction
}
}
}
你的錢一如既往BalusC。我不知道ResultSet和Statement需要關閉。謝謝。 – klonq
不客氣。 – BalusC