MySQL RAM Auslastung Teil 2

Times

Bekanntes Mitglied
Hallo,
ich habe wieder ein Problemchen mit der RAM Auslastung bei Datenbankzugriffen,
unzwar um es genauer zu sagen mit dem ResultSet.

In meinem letzten Post zu diesem Thema war das Problem das ich die ResultSets nicht immer geschlossen habe. Leuchtet mir auch ein.

In unserem Programm gibt es die Möglichkeit direkt auf ganze Datenbanktabellen zuzugreifen um ggf. eine Änderung vornehmen zu können (Nur die Daten!). Dies ist immer sehr sinnvoll für uns wenn die Datenbank auf irgendwelchen Servern von Rechenezentren liegt und man 30 Seiten Papier ausfüllen muss damit man an seiner eigenen Datenbank was verändern darf, und da aus Sicherheitsgründen nicht jeder Arbeitsplatz eine eigene Workbench / Management Studio / SQL Developer (je nachdem welches DB-System dort läuft) hat, ist dies der beste Weg für uns die Daten schnell & bequem zu ändern.
Nun in der Regel sieht das dann so aus das ich mir über diesen Service-Bereich im Programm einen Datensatz selektiere und diesen dann anpasse oder auch einfach einen neuen hinzufüge,
einen lösche etc.
Nun nach einigen Spielereien habe ich einfach mal ein "select *" ausgeführt auf eine Tabelle in welcher ~ 70MB Daten liegen (190.000 Datensätze á 64 Spalten).

RAM Auslastung für das Programm:
Nach Start: 125 MB
Resultset öffnen 1: 1384 MB
Resultset schließen 1: 1382 MB
Resultset öffnen 2: 1789 MB
Resultset schließen 2: 1779 MB

Nungut,
1. Ich habe immer gedacht das das ResultSet eine Art Pointer ist welcher auf die Daten in der Datenbank zeigt, aber wenn ich das sehe, dann speichert das ResultSet sich ja alle Daten ab.. oder wie kommt es zu dieser Menge an RAM die da verpulvert wird?
2. Nachdem ich das Resultset geschlossen habe, bleibt der RAM Verbrauch im TaskManager so gut wie stehen. Da bin ich davon ausgegangen das Java den RAM zwar für sich Beansprucht hat, aber das es auch sein kann das von diesen 1382 MB nur 200 MB zur Zeit benötigt werden. Es gab mal einen Zeitpunkt an dem Java die 1382 MB benötigt hat, hat diesen Speicher auch wieder freigegeben, aber behält sich diesen dennoch im Hinterkopf falls er mal wieder benötigt wird, aber das erklärt dann nicht das erneute öffnen eines ResultSets, da der RAM hier wieder total explodiert.
3. Ich habe Testweise mal ein System.gc() nach dem close von dem ResultSet gemacht, aber hierbei verändert sich leider garnichts.

Also für mich ist Punkt 1 am wenigsten zu verstehen. Selbst wenn ich mir alle meine Daten aus der Tabelle in ein 2 Dimensionales String Array speichere, verbrauche ich bei weitem nicht soviel RAM wie das ResultSet beim öffnen.

Bevor nun jemand sagt "Aber man macht auch kein 'select *'" .. ja, aber dadurch werde ich an dieser Stelle auch nicht klüger :)

Ich steh mit dem ResultSet echt auf Kriegsfuß. Irgendwo verstehen wir uns einfach nicht^^

Danke :)
 

Thallius

Top Contributor
Das ResultSet enthält natürlich schon alle Daten. Da ist nichts mit Pointern auf die Daten in der Datenbank. Wozu sollte das auch gut sein? Man fragt halt immer nur die Daten ab, die man auch braucht oder man läßt die Datenbank nur die Daten ändern die man geändert haben will. Dafür gibt es ja dieses magische WHERE Kommando :)

Und ich glaube einfach nicht, dass es eine Anwendung gibt, die gleichzeitig alle 190.000 Datensätze einer Tabelle brauchen wird. Denn die kann man ja gar nicht verarbeiten. Oder Willst du dem User eine Liste mit 190.000 Einträgen präsentieren? Bestimmt nicht. Du wirst sie filtern wollen und das läßt man eben über eine geeignetes Query die DB machen und macht es nicht selber.

Gruß

Claus
 

Times

Bekanntes Mitglied
Ja, da hast du natürlich vollkommen recht.

In der Anwendung selber wird alles an allen Ecken und Enden gefiltert, aber mich hat in diesem Falle mal wirklich das "select *" ohne where interessiert. Aber okay, wenn das so ist, dann soll das so sein.

Mich verwundert aber weiterhin der Effekt das es so aussieht als würde der RAM nicht freigegeben werden. Ich werden dies mal weiter testen, unzwar starte ich heute Abend einen Thread der bis morgen durchläuft und das o.g. ResultSet jede halbe Stunde einmal öffnet und dann nach 10 Minuten wieder schließt.
Wenn das Programm morgen noch läuft, ist es ja soweit in Ordnung. Ich gebe aufjedenfall Rückmeldung ob es funktioniert hat oder ob das Programm sich verabschiedet hat.
 

JStein52

Top Contributor
Wobei ich ja schon nicht verstehe wie die 70MB Nutzdaten aus der Datenbank auf 1300 MB Speicherbedarf im RAM aufgeblasen werden.
 

Meniskusschaden

Top Contributor
Wobei ich ja schon nicht verstehe wie die 70MB Nutzdaten aus der Datenbank auf 1300 MB Speicherbedarf im RAM aufgeblasen werden.
Leuchtet mir auch noch nicht ein. Normalerweise hätte ich jetzt vermutet, dass er grössere Tabellen gejoined hat. Aber er hat ja geschrieben, dass er eine Tabelle gelesen hat.

EDIT: Vielleicht hat er die ja mit sich selbst gejoined.;)
 

Thallius

Top Contributor
Hm also um 70MB Rohdaten aus der DB auf 1300MB aufzublasen bei 200.000 Zeilen, bedarf es ja nicht viel. Das bedarf ja nur ein paar Byte pro Resultset Eintrag.

Gruß

Claus
 

JStein52

Top Contributor
Hm also um 70MB Rohdaten aus der DB auf 1300MB aufzublasen bei 200.000 Zeilen, bedarf es ja nicht viel.
Das hältst du für nicht viel ? Das ist ein Faktor von fast 20 !! bei 200.000 Zeilen und 64 Spalten sind das grob 13 Mio. Eintraege pro Resultset. um auf 1300 Mio Bytes zu kommen sind das aber 100 Byte pro Eintrag ?! Oder sehe ich das falsch ?
 

JStein52

Top Contributor
Ja und was sind 100 Byte für ein Object in Java?
Kommt mir viel vor. Ich weiss zwar nicht wie ein Resultset intern arbeitet aber mal naiv angenommen er speichert jede Spalte in einer ArrayList Dann braucht eine ArrayList mit 200000 Einträgen rund 6 MByte (gerade mit einer Integer-Liste getestet). Bei 64 Spalten sind das rund 360 MByte ! Jetzt nehmen wir noch rund 70 MByte an nutzdaten dazu dann sind wir Höchstens bei 500 MByte
 

Ähnliche Java Themen

Neue Themen


Oben