JDBC 大容量复制中可能存在内存泄漏
Posted
技术标签:
【中文标题】JDBC 大容量复制中可能存在内存泄漏【英文标题】:Possible memory leak in JDBC bulkcopy 【发布时间】:2019-12-01 16:40:23 【问题描述】:我正在编写一个 Spring Boot 2 应用程序,并且我正在使用 SQL 批量复制功能在 SQL Server 2012 数据库中插入多条记录。 每次我插入 ~700 行时,我都会泄漏 600 MB
我已经尝试过 Microsoft 驱动程序版本 6.4.0.jre8 和 7.2.2.jre8,但一切都发生了变化。 我已经尝试为 tomcat 更改 Hikari 连接池,但结果是一样的。
为了调用 Microsoft API,我使用的是包装框架 (https://github.com/bytefish/JSqlServerBulkInsert),但代码很干净:
public void saveAll(Connection connection, SQLServerBulkCopyOptions options, Stream<TEntity> entities)
// Create a new SQLServerBulkCopy Instance on the given Connection:
try (SQLServerBulkCopy sqlServerBulkCopy = new SQLServerBulkCopy(connection))
// Set the Options:
sqlServerBulkCopy.setBulkCopyOptions(options);
// The Destination Table to write to:
sqlServerBulkCopy.setDestinationTableName(mapping.getTableDefinition().GetFullQualifiedTableName());
// The SQL Records to insert:
ISQLServerBulkRecord record = new SqlServerRecord<TEntity>(mapping.getColumns(), entities.iterator());
// Finally start the Bulk Copy Process:
sqlServerBulkCopy.writeToServer(record);
// Handle Exceptions:
catch (SQLServerException e)
// Wrap it in a RunTimeException to provide a nice API:
throw new RuntimeException(e);
当我使用 Eclipse 内存分析器时,我得到了以下结果:
与光:使用 Tomcat:“com.zaxxer.hikari.pool.PoolEntry”的一个实例由加载 “sun.misc.Launcher$AppClassLoader@0x81611758”占用640.619.616 (95,94 %) 个字节。内存是在一个实例中累积的 “”加载的“java.lang.Object[]”。
关键字 com.zaxxer.hikari.pool.PoolEntry java.lang.Object[] sun.misc.Launcher$AppClassLoader @ 0x81611758 "
“加载了“org.apache.tomcat.jdbc.pool.ConnectionPool”的一个实例 由“sun.misc.Launcher$AppClassLoader @ 0x81614fa0”占用 640.805.840 (95,92 %) 字节。内存在“”加载的“java.lang.Object[]”的一个实例中累积。
关键字 java.lang.Object[] sun.misc.Launcher$AppClassLoader @ 0x81614fa0 org.apache.tomcat.jdbc.pool.ConnectionPool"
【问题讨论】:
你怎么知道这是泄漏而不是内存尚未被 GC 回收?调用close()
并不能保证立即从内存中删除所有数据。
我在强制 GC 并且 600 MB 的差距没有改变。 Eclipse Memory Analyzer 也将其检测为可能的泄漏
【参考方案1】:
不是司机。我在方法中使用了一个列表,并希望在方法范围之后被收集。我将引用分配给 null(之前我清除了集合),GC 可以收集它。
【讨论】:
以上是关于JDBC 大容量复制中可能存在内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
什么调试器可以检查 C++ 代码是不是存在内存泄漏? [复制]