Wird ResultSet auslaufen, wenn es nicht explizit geschlossen wird?

Ich verwende das JDBC-Verbindungs-Pooling mit Jetty und habe dieses Setup über ein Jahr lang auf einer Serverinstanz ohne Probleme ausgeführt. Ich habe auf einen neuen Ubuntu-Server gewechselt und immer noch keinen Speicher mehr. Ich analysiere die Speichernutzung und sehe die folgenden erstklassigen Instanzen:

java.util.Hashtable$Entry (33%)
com.mysql.jdbc.ConnectionPropertiesImpl$BooleanConnectionProperty (13%)
com.mysql.jdbc.ConnectionPropertiesImpl$StringConnectionProperty (3%)
com.mysql.jdbc.ConnectionPropertiesImpl$IntegerConnectionProperty (3%)

Ich schließe meine ResultSet-Instanzen nicht explizit, sondern mache Folgendes:

Connection conn = null;
PreparedStatement stmt = null;
try {
    conn = ...;
    stmt = ...;
    ResultSet rs = ...;
    rs.useIt();
}
finally {
    if (stmt != null) { stmt.close(); }
    if (conn != null) { conn.close(); }
}

Die Dokumentation besagt, dass die Anweisung zugeordnete ResultSet-Instanzen schließt, wenn sie geschlossen wird. Ist es möglich, dass die JDBC-Implementierung auf diesem Ubuntu-Computer dies nicht tatsächlich tut? Ich habe keine Änderungen an meinem Code vorgenommen (eine gepackte .war-Datei). Ich habe ihn einfach in einer Jetty-Instanz auf diesem Ubuntu-Computer abgelegt, wie er ist.

Die Profilerstellung zeigt, dass die Instanzen von com.mysql.jdbc.ConnectionPropertiesImpl weiter wachsen. Vermutlich geschieht dies also.

Ich wollte nur überprüfen, bevor ich loslege und meinen gesamten Code ändere, um die ResultSet-Instanzen explizit zu schließen. Wenn ich auf MySql Workbench schaue, sehe ich in der Ansicht "Client-Verbindungen" nichts Außergewöhnliches - meine App-Verbindungen kommen herein und scheinen bereinigt zu werden.

Vielen Dank

-------------------- Update --------------------

Ich habe alle meine Instanzen von ResultSet geändert, um sie sofort sowie im finally {} -Block zu schließen, genau wie meine Connection- und PreparedStatement-Instanzen. Das scheint aber nicht zu helfen, das Gedächtnis wächst weiter.

Beim Stöbern bemerkte ich die Klasse:

com.mysql.jdbc.JDBC4Connection

und die Anzahl der Instanzen nimmt nie ab. Nach ungefähr 10 Minuten sehe ich fast 5k Instanzen (yikes?).

Dieser Beitrag sieht dem sehr ähnlich, auf das ich stoße:

Speicherverlust in JDBC4Connection

Das OP sagt am Ende:

Der ORM verließ sich darauf, die Verbindung zu freien Ressourcen im Finalizer zu schließen (manchmal über das Schließen der Ergebnismengen und Anweisungen), aber der Pool ließ die Verbindungen mehrere Stunden offen, und im Falle eines Spitzenwerts verursachte dies OOM.

Ich verstehe nicht, was das bedeutet oder wie man das beheben würde. Ich bin mir ziemlich sicher, dass ich meine Ressourcen jetzt überall schließe (ansonsten, als ich dieselbe Webanwendung auf meinem anderen Windows-Server ausgeführt habe, habe ich möglicherweise auch dort ein Leck gesehen?).

-------------------- Update --------------------

Da ich immer noch das gleiche Verhalten sehe, öffne ich in jeder Anfrage, die ich bearbeite, eine Datenbankverbindung (Fehlerprüfung weggelassen):

 public class DsHelper {
    private static DsHelper sInstance;
    private DataSource mDs;

    public DsHelper() {
        InitialContext ctx = new InitialContext();
        mDs = (DataSource)ctx.lookup("java:comp/env/jdbc/myds");
    }

    public static DsHelper get() { 
        if (sInstance == null) {
            sInstance = new DsHelper();
        }

        return mInstance;
    }

    public DataSource getDataSource() {
        return mDs;
    }
}

es benutzen:

protected void doGet(HttpServletRequest request, 
                     HttpServletResponse response) 
{
    Connection conn = null; 
    try {
        conn = DsHelper.get().getDataSource();
        ...
    }
    finally {
        if (conn != null) { conn.close(); }
    }
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage