Contain SQL Server JDBC getIndexInfo() Memory Growth

If heap use grows only when schema metadata is refreshed, count calls to DatabaseMetaData.getIndexInfo() and correlate retained objects with individual pooled connections. Closing the returned ResultSet is necessary, but a driver defect can still retain an internal statement.

Last updated: November 9, 2026.

DatabaseMetaData meta = connection.getMetaData();

try (ResultSet indexes = meta.getIndexInfo(
        connection.getCatalog(), "dbo", "orders", false, false)) {
    while (indexes.next()) {
        cacheIndex(indexes.getString("INDEX_NAME"));
    }
}

// Cache metadata by schema version; do not call this per request.

The try-with-resources block closes the public result set correctly. If retained memory still increases on the same physical connection, reduce call frequency and compare driver versions rather than adding application references to the result.

Prove the growth belongs to the driver path

Microsoft’s database metadata guide describes the SQL Server JDBC metadata API. Build a small loop against one physical connection, take heap histograms before and after a fixed number of calls, and repeat with pooling disabled. Record the driver JAR, Java version, server version, and whether the connection is SQL Server or Azure Synapse.

A current mssql-jdbc report attributes per-call retention in versions 13.2 through 13.6 to an internal prepared statement on the regular SQL Server path. Treat that range as reported evidence, not proof for every workload; reproduce it with your exact driver.

Mitigate without hiding pool exhaustion

Do not introspect indexes for every request. Cache metadata with the application’s schema or migration version, and refresh it only after a deployment that changes indexes. As a temporary containment measure, recycle affected physical connections after a bounded lifetime and alert on both heap growth and pool churn.

Track the official JDBC driver release notes and test the first release that documents the fix. Compare retained heap and functional metadata output before upgrading production. Avoid downgrading blindly because older drivers can miss newer SQL Server types and fixes. Preserve the minimal reproducer so the workaround can be removed when the corrected driver passes it.

Related Web Cheat Sheet guides

Sergey Kornilov

Sergey Kornilov