kontinuierlicher Speicheranstieg bei DB abfrage

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hallo, ich mache gerade in einer Firma Praktikum und soll zur Zeit ein Javaprogramm entwickeln, was von mehreren Datenbanken, verschiedene Tabellen und Datensätze einliest und diese in einer neuer Datenbank als Datensicherung speichert. Funktioniert alles soweit auch wunderbar wenn da nicht ein großes Problem wäre: der Speicherverbrach wächst kontinuierlich(und das Programm ist für den Dauerbetrieb konzipert und hat eine Abfrage/Aktualierungsrate von 5 sek). Habe hierfür eine extra Klasse implementiert:
Kann mir da jemand helfen, bin am verzweifeln!!
(GC arbeitet auch tadlelos, habe das mit jstat geprüft)

package datenbank;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;




/**
* Steht für die Implementierung der Selectabfrage
* !!!Einschränkung: es können maximal immer 10000 Datensätzegelesen werden!!!
*
*/
public class DatenbankS implements DatenbankT {

/**speichert den Datensatz, der durch die Abfrage entstanden ist*/
private static String[][] datensatz;

/**beinhaltet, ob der die Abfrage fehlerfrei durch geführt wurde*/
private static boolean status;

/**die anzahl der Zeilen*/
private static int zeilen;

/**die Anzahl der Spalten*/
private static int spalten;

/**die ausgegebene Fehlermeldung*/
private static String error;

/**Abfrage speichern*/
private String query,url,user,pw,treiber;

/**Speichernung, ob offene Verbindung vorhanden*/
private boolean isOpen;

/**Speicher die Verbungsdaten*/
private Connection con;

/**Zeigt die Anzahl der Datensätze, die maximal auf einmal geholt werden können,
* bei 0 wird keine Beschränkung auferlegt*/
public final static int ANZ_DATENSAETZE = 10000;

private ResultSet rs;

private Statement stmt;


/**
* Konstruktor
*
* baut die Verbindung auf und fragt die Daten ab.
*
* @param t - treiber über den JDBC die verbindung herstellt
* @param url - entweder die URl oder die DSN bei ODBC verbindungen

*/

public DatenbankS(Treiber t, String url) {

this.url = t.getConnection() + url;
treiber = t.getTreiber();
zeilen = 0;
spalten = 0;
error = "";
status = true;
isOpen = false;

}//Datenbankverbindung



/**
* baut die Verbindung auf und fragt die Daten ab.
*
* @param query - erwartet den Abfrage String
* @param url - die ODBC Verbindung
* @param user - benutzername
* @param pw - passwort
*
*/
public void connect(String user, String pw){

this.user = user;
this.pw = pw;

//!!!!ACHTUNG!!!! UNTERSCHEIDUNG DER ABFRAGEN NOCH VON NÖTEN -z.Zt. nur Select
try {
//Load the jdbc-odbc bridge driver
Class.forName (treiber);
//DriverManager.setLogStream(System.out);

//Connect zum ODBC Treiber
con =
DriverManager.getConnection (url,this.user,this.pw);
//con.setAutoCommit(false);
isOpen = true;

//wenn kein Connectivität, dann hier exception
checkForWarning (con.getWarnings ());

}//try
catch (SQLException ex) {
status = false;
System.out.println ("\n*** SQLException caught ***\n");
while (ex != null) {
System.out.println ("SQLState: " +
ex.getSQLState ());
System.out.println ("Message: " + ex.getMessage ());
error = "Fehler bei SELECT: "+ex.getMessage();
System.out.println ("Vendor: " +
ex.getErrorCode ());
ex = ex.getNextException ();
System.out.println ("");
}//while
}//catch
catch (java.lang.Exception ex) {
//evtentuell andere Exceptions
ex.printStackTrace ();
}//catch
}//connect

/**
* baut die Verbindung auf und fragt die Daten ab.
*
* @param query - erwartet den Abfrage String
* @param url - die ODBC Verbindung
* @param user - benutzername
* @param pw - passwort
*
*/
public boolean abfragen(String query){

//speichert die Query für die Count anweisung
this.query = query;



if(!check())return false;

//!!!!ACHTUNG!!!! UNTERSCHEIDUNG DER ABFRAGEN NOCH VON NÖTEN -z.Zt. nur Select
try {

//Anzeigen welche Verbindung es ist, damit, richtige Abfarge errstellt werden kann
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

if(!(ANZ_DATENSAETZE == 0))stmt.setMaxRows(ANZ_DATENSAETZE);
//Schickt anfrage zur Datenbank - und speichert sie im resultset
rs = stmt.executeQuery(this.query);
//temp = rs.

rs.last();
zeilen = rs.getRow();
rs.beforeFirst();

int pos = 0;
String out;
//speichert lesbare DATEN in rsmd
ResultSetMetaData rsmd = rs.getMetaData ();

//anzahl der Spalten
spalten = rsmd.getColumnCount ();

datensatz = new String[spalten][zeilen];
//zeilenzeiger wieder an die erste Pos
boolean more = rs.next();
//solange noch zeilen vorhanden sind, lese sie aus
while (more) {
pos++;
for (int i=1; i<=spalten; i++) {
out = rs.getString(i);
datensatz[i-1][pos-1] = out;
}//for
more = rs.next ();
}//while
rs.close();


//Close the statement
this.stmt.close();
System.gc();
isOpen = true;

}//try
catch (SQLException ex) {
status = false;
System.out.println ("\n*** SQLException caught ***\n");
while (ex != null) {
System.out.println ("SQLState: " +
ex.getSQLState ());
System.out.println ("Message: " + ex.getMessage ());
error = "Fehler bei SELECT: "+ex.getMessage();
System.out.println ("Vendor: " +
ex.getErrorCode ());
ex = ex.getNextException ();
System.out.println ("");
}//while
}//catch
catch (java.lang.Exception ex) {
//evtentuell andere Exceptions
ex.printStackTrace ();
}//catch

return true;
//test();
}//connect

/**
* schliesst die Verbindung
*
*/
public void disconnect(){

try {
if(!con.isClosed()){

//Close the connection
con.close();
isOpen = false;//isOpen
}//if
}//try
catch (SQLException ex) {
status = false;
System.out.println ("\n*** SQLException caught ***\n");
while (ex != null) {
System.out.println ("SQLState: " +
ex.getSQLState ());
System.out.println ("Message: " + ex.getMessage ());
error = "Fehler bei INSERT: "+ex.getMessage();
System.out.println ("Vendor: " +
ex.getErrorCode ());
ex = ex.getNextException ();
System.out.println ("");
}//while
}//catch
catch (java.lang.Exception ex) {
//evtentuell andere Exceptions
ex.printStackTrace ();
}//catch

}//disconnect



/**
* Wenn die ersten Zeichen eine korrekte Anweisung enthalten, so wird true zurück
* gegeben und die Art der Anweisung gespeichert!
*
* @return ob der Abfrage String eine Select anweisung ist
*/
private boolean check(){

if(query.substring(0,6).toUpperCase().equals("SELECT")){
return true;
}//if

error = "Fehler bei SELECT: Die Abfrage war keine gültige Abfrabe, überprüfen Sie diese";
status = false;
return false;

}//

/**
* Erzeugt eine Warnmeldung oder Info vom SQL Server mit Ausgabe
* @param warn - die Warnmeldung
* @throws SQLException
*/
private static void checkForWarning (SQLWarning warn)throws SQLException {
if (warn != null) {
System.out.println ("\n *** Warning ***\n");
while (warn != null) {
System.out.println ("SQLState: " +
warn.getSQLState ());
System.out.println ("Message: " +
warn.getMessage ());
System.out.println ("Vendor: " +
warn.getErrorCode ());
System.out.println ("");
warn = warn.getNextWarning ();
}//while
}//if
}//checkForWaring


/**
* Does ...
*
*
* @return
*/
public String[][] getDaten() {
// your code here
return datensatz;
}

/**
*
* @return die Anuahl der Zeilen
*/
public int getZeilen() {
// your code here
return zeilen;
}

/**
*
* @return die Anzahl der Spalten
*/
public int getSpalten() {
// your code here
return spalten;
}

/**
* Zeigt an, ob die Abfarge fehlerfrei verlaufen ist
*
*
* @return true- wenn die Abfrage fehlerfrei war
*/
public boolean getStatus() {
// your code here
return status;
}

/**
* gibt, wenn vorhanden, die SQL Fehlermeldung zurück
* @return Fehlermeldung
*/
public String getFehler(){
return error;
}//

/**
* gibt zurück, ob bereits eine offene Verbindung besteht
*
* @return true/false
*/
public boolean isOpen(){
return isOpen;
}//isOpen
}
 
S

SlaterB

Gast
Datenbank komplett raus, Array mit 10.000 Dummy-Inhalten füllen, evtl. bisschen verzögern falls schneller als DB,

was passiert dann im Laufe der Zeit?
 
S

SlaterB

Gast
na komplett raus im eigentlichen Sinne, auskommentieren oder wie auch immer

public boolean abfragen(String query){
array = dummy-Array mit 10.000 Sätzen;
return true;
}

wenn du dann immer noch das Speicherproblem hast,
dann hat das alles gar nix mit der DB zu tun
sondern z.B. damit wo dieses Array dauerhaft im Speicher gehalten wird
 
S

SireHages

Gast
Also ich habe das soweit gemacht, wie du es gesagt hast!
Habe zuerst die Abfrage auskommentiert bzw. in der methode war nur noch ein "Arraycopy" enthalten, so wie du es gesagt hattest!

Ergebnis: weiter konstanter Speicheranstieg

Danach habe ich noch zusätzlich die Methode Connect auskommentiert!

Ergebnis: anfänglichlicher Speicheranstieg(ca. 30sec), danach konstanter Wert der jeweils um 4KB schwankt - also konstant

Daraus folgere ich: Es liegt irgendwo beim Verbindungsaufbau
(korregiert mich, wenn ich was übersehen habe)

Achso: ich poste mal zum besseren Verständnis ein Stück Source Code, wie die Klasse Datenbank genutzt wird im Allgemeinen(nur struktureller Aufbau, keine sinnvolle funktionalität dahinter).

DatenbankT db;//interface

while(true){
db = new DatenbankS(Treiber.ODBC,URL1);
db.connect(USER1, PW1);
db.abfragen("SELECT ");
db.disconnect();

db = new DatenbankS(Treiber.ODBC,URL2);
db.connect(USER2, PW2);
db.abfragen("SELECT ");
db.disconnect();
}
 

Caffè Latte

Bekanntes Mitglied
Hi,

setzt mal für alle nicht benötigten Objekte die Referenz auf null (db =null; resultset = null; statement = null; etc.pp).
 
S

SlaterB

Gast
tja, das ist nicht ganz das was ich gehofft habe,
denn bei sowas wie Connection passiert das meiste im Hintergrund, da fällt mir nix zu ein,

du könntest ein bisschen rumprobieren,
z.B. wird das Class.forName() sicherlich nur einmal pro Treiber benötigt,
die Connections selber statisch halten und wiederbenutzen?

vielleicht mal nach anderen Programmen im Netz schauen, die auch Connections verwenden,
und testen, ob dort bei Mehrfachnutzung das gleiche Problem auftritt,

ich kann da gar nix zu testen, da mir die Infrastruktur zum Ausführen fehlt
 

homer65

Top Contributor
So arbeitet man auch nicht. Man macht nicht für jede Abfrage eine neue Datenbankverbindung auf. Das ist zuviel Overhead. Vielmehr macht man einmal am Anfang eine Verbindung auf (connect). Dann macht man die Abfragen. Und erst am Ende, so es denn eins gibt, wird die Verbindung beendet. Um Ressourcen, die man in der Datenbank hält, freizugeben gibt es den Befehl "COMMIT", falls nicht sowieso schon "AUTOCOMMIT" eingeschaltet ist.
 
S

SireHages

Gast
@homer65:
das beispiel bezieht sich auf verschiedene Datenbanken(URL1,URL2)
zwischen connect und disconnect mache ich sonst verschiedene Abfragen. Ich denke mal das du das meintest.

Ich denke nun das ich den Fehler auf die schliche gekommen bin:
in der Methode disconnect, wird die Verbindung nur geschlossen, wenn sie zu ist(wie sinnlos von mir), soll heissen, es bleibt immer eine Verbindung bestehen. Problem ist aber nun, wenn ich diese schliesse bekomme folgende Exception von con.close():

[Microsoft][ODBC SQL Server Driver]Ungültiger Transaktionsstatus

-soll heissen, die Transaktion ist noch nicht abgeschlossen.
Bekomme das Problem jedoch nicht in den Griff
 
S

SlaterB

Gast
was ist denn mit einem Aufruf wie con.commit();
falls es sowas in der Art gibt?

noch irgendwelche Statements/ ResultsSets offen?
wiederum der Aufruf: kopiere dir erstmal ein funktionierendes JDBC-Beispiel von irgendwo her,
bevor du dich über Fehler in eigenen falsch zusammengebauten aufregst

probiere es erst mal mit einfachen Anfragen von EINEM Datensatz statt 10.000

es kann natürlich immer andere Ursachen haben,
aber wenn ein aus dem Internet kopiertes Beispiel nur mit Anpassung von Treiber/ User/ PW/ DB/ Tabellen/ Attributnamen nicht zum gleichen Fehler führt,
dann ist wohl wieder was in deinem Programm faul
 
S

SireHages

Gast
also ich habe alle Statements und ResultSets geschlossen

Habe es nun so, gemacht, das ich konstant nun ingesamt 6 Verbindungen zu verschiedenen Datenbanken offen lasse. Das wollte ich eigentlich nicht, da falls den Leuten hier in der Firm irgendwann mal einfällt nen exklusiven zugriff darauf einzurichten, wird kritisch.

Commit habe ich nicht genutzt, da ich den Austocommitmode bewusst auf True hatte(ist ja eh default).

Der Speicheranstieg ist zur Zeit nur noch sehr sehr gering(langzeittest steht noch aus).Die Frage die sich mir nur noch abschliessend stellt ist, warum es durch ständiges Öffnen und Schliessen zu einem solch starken Speicheranstieg kommt. Habe eigentlich alles zum Thema disconnect beachtet!!

Danke an alle die mir versucht haben zuhelfen.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Wie kann ich eine Jtable mit Inhalt einer SQL Abfrage füllen Datenbankprogrammierung 14
J SQLite Abfrage fehlerhaft - komme nicht weiter - please help. Datenbankprogrammierung 3
L PostgreSQL Abfrage mit EclipseLink Datenbankprogrammierung 7
S Berechnung des Datumsunterschieds in der SQL-Abfrage Datenbankprogrammierung 1
Zrebna Probleme bei Überführung von SQL-Code in eine HQL-Abfrage Datenbankprogrammierung 3
btwX28 mysql abfrage über phpmyadmin Datenbankprogrammierung 8
M Alle Records Felder kriegen für DB Abfrage Datenbankprogrammierung 14
pkm PostgreSQL Kann mit mybatis einen Parameter für eine postgreSQL-Abfrage nicht übergeben. Datenbankprogrammierung 5
nonickatall MySQL SQL Abfrage erneut ausführen oder rs aktualisieren Datenbankprogrammierung 14
Kirby.exe Verständnisproblem bei SQL Abfrage Datenbankprogrammierung 27
N SQL-Abfrage in JTextField ausgeben Datenbankprogrammierung 6
N java sql abfrage bestimmer Datumszeitraum Datenbankprogrammierung 9
F Mapping einer SQL Abfrage in eine Klasse Datenbankprogrammierung 4
N Java Abfrage über GUI, Daten hinzufügen Datenbankprogrammierung 54
Bluedaishi Datenbank Abfrage Datenbankprogrammierung 36
W MySQL DB Abfrage in Array, gemischte Array, generelles vorgehen Datenbankprogrammierung 4
D SQL Abfrage optimieren Datenbankprogrammierung 35
D MySQL Abfrage Datenbankprogrammierung 5
D MySQL Abfrage sortieren Datenbankprogrammierung 4
D MySQL Abfrage SUM datediff Datenbankprogrammierung 3
D Regelmäßige Abfrage aus Workbench Datenbankprogrammierung 6
M SQL-Statement Hilfe bei SQL-Abfrage Datenbankprogrammierung 2
D Abfrage - Spalte(Datum) ändern (Oracle) Datenbankprogrammierung 7
D Datenbank Abfrage Datenbankprogrammierung 7
H MySQL Benutzer Login System mit Datenbank Informationen (Abfrage zu User ist auf DB gesichert) Datenbankprogrammierung 42
D MySQL Abfrage mit kumulierten Werten Datenbankprogrammierung 16
M MySQL Anbindung und Abfrage an die Datenbank Datenbankprogrammierung 2
RowdyN SQLite Einfache Abfrage mit temporäre Tabelle, die nur innerhalb der Abfrage gültig ist Datenbankprogrammierung 0
E Abfrage auf HSQLDB Datenbankprogrammierung 4
M MySQL SQL Abfrage in JTable mit Berechnung Datenbankprogrammierung 3
S Abfrage von Gruppentickets(Mehrere Resorts an einem Tag) Datenbankprogrammierung 1
S SQL Abfrage Datenbankprogrammierung 2
F Abfrage der letzten Einträge Datenbankprogrammierung 2
J SELECT Abfrage/Suche Datenbankprogrammierung 4
U SQLite Für mich etwa komplexe Abfrage via 2 Tabellen Datenbankprogrammierung 5
OnDemand SQL Abfrage und Equals Datenbankprogrammierung 4
B MySQL MySQL-Abfrage von aufsummierter Zeit Datenbankprogrammierung 3
M MySQL MySQLSyntaxError in Java, obwohl Abfrage in HeidiSQL korrekt Datenbankprogrammierung 2
ruutaiokwu sql abfrage mit rekursion, mit oder ohne cte... Datenbankprogrammierung 5
J SQLite Abfrage ausführen stoppt für Zyklus? Wie es zu lösen? Datenbankprogrammierung 3
L JSONArray/JSONObject MySQL-Servlet Abfrage Datenbankprogrammierung 2
H Derby: SYSCS_UTIL.SYSCS_EXPORT_QUERY mit String Abfrage in wehre-Klausel nicht möglich Datenbankprogrammierung 3
L SQL-Abfrage bricht vor dem Ende ab Datenbankprogrammierung 2
S MySQL Abfrage über mehrere Tabellen + Einträge werden überschrieben Datenbankprogrammierung 1
M Derby/JavaDB Komplexe Abfrage vereinfachen Datenbankprogrammierung 2
S SQL-Abfrage, Filewriter .txt Datei Datenbankprogrammierung 2
P Datenbank- Abfrage mit null'en Datenbankprogrammierung 2
Bluedaishi MySQL Abfrage Problem :-) Datenbankprogrammierung 21
D MySQL Erstellen der richtigen Abfrage Datenbankprogrammierung 3
D MySQL DB Abfrage Prüfen Datenbankprogrammierung 10
D JDBC insert mit select abfrage Datenbankprogrammierung 5
E PostgreSQL Exception too ...many clients already bei DB-Abfrage Datenbankprogrammierung 14
M MySQL SQL Abfrage Problem Datenbankprogrammierung 6
W No data found: SQL-Abfrage funktioniert nur beim Debuggen Datenbankprogrammierung 3
E Abfrage nach existierender SQL-Tabelle Datenbankprogrammierung 7
H JSON Array abfrage beschleunigen Datenbankprogrammierung 2
S MySQL Abfrage: Wenn Feld leer, alles anzeigen Datenbankprogrammierung 5
Mrtwomoon Abfrage-Ergebnisse in einem Fenster darstellen Datenbankprogrammierung 8
0 SQL Abfrage Bestellung Datenbankprogrammierung 15
G SQLite SQLite Abfrage Datenbankprogrammierung 4
C Mit jsp über Java eine DB Abfrage durchführen --> java.lang.ClassNotFoundException Datenbankprogrammierung 4
Dit_ Hibernate, effiziente SQL-Abfrage definieren Datenbankprogrammierung 5
B My-SQL Abfrage - Out Of Memory Error Datenbankprogrammierung 13
C MySQL Problem mit UPDATE Abfrage Datenbankprogrammierung 13
K SQLite Einfache DB-Abfrage Datenbankprogrammierung 2
C Problem mit SQL-Abfrage Datenbankprogrammierung 5
C Sortierung bei SQL-Abfrage Datenbankprogrammierung 3
B Bei Abfrage schießt der Speicher in die Höhe Datenbankprogrammierung 6
M SQL Abfrage Dupliakte bei Kreuzvergleich Datenbankprogrammierung 2
M Access Abfrage mit Parameter & Access/Java liefern unterschiedliche Ergebnisse Datenbankprogrammierung 2
G SQL Abfrage Datenbankprogrammierung 5
C SQL-Abfrage Datenbankprogrammierung 4
B SQL-Abfrage Datenbankprogrammierung 4
R SQL Abfrage, je nach ausgewählten Parametern Datenbankprogrammierung 11
C Wert in SQL-Abfrage zählen lassen Datenbankprogrammierung 8
R Memory leaks bei DB Abfrage Datenbankprogrammierung 16
S Abfrage auf SQLite-DB Datenbankprogrammierung 2
I Belastet es das System zu sehr einen Timer jede 0.2 Sekunden eine DB Abfrage machen zu lassen? Datenbankprogrammierung 9
L MySQL Probleme mit PreparedStatement für SQL-Abfrage in Java Datenbankprogrammierung 2
G Abfrage von Teilnehmern Datenbankprogrammierung 4
B HSQLDB Probleme mit Select...Where Abfrage Datenbankprogrammierung 16
G JOIN Abfrage über mehrere Tabellen Datenbankprogrammierung 15
F MySQL SQL Abfrage für u.a. Spaltenname key Datenbankprogrammierung 4
G SQLite Abfrage, ob in Tabelle X Spalte Y existiert Datenbankprogrammierung 4
A MySQL Ergebnss aus SQL Abfrage in Hauptklasse verwenden Datenbankprogrammierung 3
N Geschwindigkeit bei if Abfrage Datenbankprogrammierung 11
J sql abfrage ... Problem mit Datumswert Datenbankprogrammierung 3
G Performante SQL- Abfrage (LIKE %) Datenbankprogrammierung 21
G Join Abfrage Datenbankprogrammierung 12
M db abfrage fehlerhaft Datenbankprogrammierung 5
C MySQL Abfrage mit flexibler WHERE bedingung Datenbankprogrammierung 10
C Datenbank-Abfrage, if im Select Datenbankprogrammierung 9
S MySQL Frage zu LeftJoin Abfrage Datenbankprogrammierung 2
G SQL Abfrage über mehrere Tabellen Datenbankprogrammierung 28
H SQL Abfrage - zwei tabellen vergleichen. Datenbankprogrammierung 2
H MySQL Datenbank Abfrage Datenbankprogrammierung 10
André Uhres SQL Abfrage erkennt keine Buchstaben mit Akzenten (z. B. é, è) Datenbankprogrammierung 3
E MySQL Klasse zur Abfrage statisch oder Standard Datenbankprogrammierung 5
J Mit einer Abfrage Worte suchen die in Zwei Tabellen enthalten sind Datenbankprogrammierung 5
G M:N Abfrage Datenbankprogrammierung 2

Ähnliche Java Themen


Oben