2010-05-20 3 views
5

Ein wenig Hintergrund über die Anwendung, die ich werde darüber reden in den nächsten paar Zeilen am:Oracle T4CPreparedStatement Speicherlecks?

XYZ ist ein Datenmaskierungswerkbank RCP Anwendung Eclipse: Sie es eine Quelle Tabellenspalte geben, und eine Zieltabelle Spalte, würde es eine Transformation (Verschlüsselung/Shuffling/etc) anwenden und die Zeilendaten von der Quellentabelle in die Zieltabelle kopieren. Wenn ich jetzt n Tabellen maskiere, werden n Threads von dieser App gestartet. Hier

ist die Frage:

I in eine Produktions Problem ausgeführt haben auf der ersten Rolle aus der oben genannten App. Leider habe ich keine Logs, um an die Wurzel zu gelangen. Ich habe jedoch versucht, diese App in Testregion zu betreiben und einen Stresstest durchzuführen.

Als ich .hprof-Dateien sammelte und sie durch einen Analysator (yourKit) lief, bemerkte ich, dass die Objekte von oracle.jdbc.driver.T4CPreparedStatement den Heap speicherten. Die Analyse sagt mir auch, dass eine meiner Klassen einen Verweis auf dieses vorbereitete Anweisungsobjekt enthält und dadurch n Threads n solche Objekte haben. T4CPreparedStatement schien Zeichenarrays zu haben: lastBoundChars und bindChars jeder Größe char [300000].

Also recherchierte ich ein bisschen (Google!), Erhielt ojdbc6.jar und versuchte, T4CPreparedStatement zu dekompilieren. Ich sehe, dass T4CPreparedStatement OraclePreparedStatement erweitert, die die Array-Größe von lastBoundChars und bindChars dynamisch verwaltet.

So sind meine Fragen hier:

  1. Haben Sie schon einmal in ein Problem laufen wie dieses?
  2. Kennen Sie die Bedeutung von lastBoundChars/bindChars?
  3. Ich bin neu zu Profiling, so dass Sie denke, ich mache es nicht richtig? (I lief auch die hprofs durch MAT - und das war die Haupt identifiziert Problem - so, ich glaube nicht wirklich ich falsch sein könnte?)

Ich habe etwas Ähnliches auf dem Netz gefunden hier : http://forums.oracle.com/forums/thread.jspa?messageID=2860681

Schätzen Sie Ihre Vorschläge/Ratschläge.

+0

1. Ja. 2. Ja. 3. Nr. Auf der Oracle-Website gibt es ein Whitepaper, in dem die technischen Kompromisse in diesen Bereichen erläutert werden. http://www.oracle.com/technology/tech/java/sqlj_jdbc/pdf/memory%20management%20aug%202009.pdf –

+0

Ich kam auch in das gleiche Problem. Hast du irgendwelche Lösungen? –

Antwort

8

Während es möglich ist, scheint es unwahrscheinlich, dass Sie ein großes Speicherleck in 11g gefunden haben. Ich würde anfangen, indem ich die tatsächliche SQL von den durchgesickerten Cursorn und in Code für wo ersuchte, SQL erhalte. Eine sehr häufige Ursache für durchgesickert Cursor ich in der Vergangenheit gefunden haben, ist der Code wie folgt:

try { 
PreparedStatment stmt = null; 
stmt = con.prepareStatement("SOME AWESOME SQL"); 
//lots of lines of code that masks the problem 
stmt = con.prepareStatment("DIFFERENT SQL"); //You just leaked "SOME AWESOME SQL"!!! 
//lots more code 
} finally { 
stmt.close() //looks like everything is ok, but only the second one actually got closed 
} 
+0

Affe, danke, für den Hinweis. Ich werde meinen Code scannen und Updates posten – Jay

11

ich das gleiche Problem aufgetreten. Obwohl Affes Leck das Problem sein könnte, war das nicht mein Problem und ich fand eine andere Antwort nach einigem Graben:

Der Oracle JDBC Treiber enthält Puffer, in denen Daten als Leistungsoptimierung gelesen werden. Die Puffergröße wird basierend auf der maximal möglichen Zeilengröße berechnet (also würde VARCHAR(2000) so etwas zuweisen wie 2000 char s), multipliziert mit der JDBC-Abrufgröße. Dies ermöglicht dem Treiber, Daten direkt in den Puffer zu lesen, anstatt auf Anforderung zuzuordnen, was (anscheinend) langsamer wäre.

Jede vorbereitete Anweisung in jeder Verbindung verwaltet einen Puffer dieser Art. Wenn Sie einen großen Verbindungspool mit Anweisungspufferung verwenden (oder Sie PreparedStatement Objekte manuell zwischenspeichern oder sie auslaufen lassen), können Sie schnell viel Heapspeicherplatz verbrauchen. 1,6 GB in meinem Fall!

Dies alles wird von Oracle sich in einem auf dem 11.2.0.3 Treiber basiert

Meine Erfahrung PDF here erklärt.