SQLite Library frisst kompletten RAM

Paddy.

Aktives Mitglied
Ich hab eine etwas mehr als ein GB große Datenbank.
Die Werte werden nur gelesen und mit bestimmten Vergleich Tests verarbeitet aber die Ausgabe erfolg dann in ne normale Text-Datei.
Ich hab meinem JAVA Programm Parameter "-Xms100m -Xmx1300m" also sollte das Java Programm die 8GB Ram nicht komplett belegen. ;(
Insgesammt wird zwar irgendwann die komplette DB geladen aber das sollte ja nicht den kompletten Ram fressen, da ich ja nicht alles cache. Sobald der Ram voll frisst es sich noch durch den SWAP.
Ich hab von Xerial verschiedene Versionen getestet 3.8.7, 3.8.6 (Ich hab noch ne 4er Version die aber erst gar nicht startet).
bei SQLiteConfig hab ich mehres zum rumprobieren und einstellen gefunden, allerdings ohne Ergebnis.
Hier der Teil der die Connection erzeugt:
Java:
Class.forName("org.sqlite.JDBC");
String connectionCommand;
org.sqlite.SQLiteConfig config = new org.sqlite.SQLiteConfig();
config.setReadOnly(true);
config.setSharedCache(false);
config.setJounalSizeLimit(-1);
config.setPageSize(1024);
config.setCacheSize(200);
connectionCommand = "jdbc:sqlite:" + file;
this.connection = DriverManager.getConnection(connectionCommand,config.toProperties());

kann mir jmd erklären was einzustellen ist das Speicher nicht so extrem benutzt wird????:L
 

Thallius

Top Contributor
Ganz einfach:

Wenn Du die ganze DB einließt dann hast Du das Prinzip einer DB nicht verstanden und solltest dich da erstmal einarbeiten.

Gruß

Claus
 

Paddy.

Aktives Mitglied
Ich hab das Prinzip schon verstanden :) Vielleicht ist oben schlecht formuliert. Ich lese nicht als erstes die kompletten 1,3GB in Java-Objekte ein!!
Die Datenbank wird nicht direkt komplett eingelesen, sondern Schrittweise in Blöcken. Sobald ein Block durch gearbeitet ist sind die Werte dieses nicht mehr relevant.
Ich benötige die Datenbank um effizient an die Werte zu kommen und damit Ähnlichkeitstest zu machen.
 

Joose

Top Contributor
Sorgst du auch dafür das diese Objekte dann nicht mehr referenziert werden? So dass der GC den Speicher freiräumen kann wenn benötigt?
 

Paddy.

Aktives Mitglied
wie man an den Java-Parameter sieht, erlaube ich nicht das Java mehr als 2GB frisst. Also liegt das Problem in der nativen SQLite Bibliotek und nicht in Java. Aber die nicht benötigten Objekte werden nicht mehr referenziert.
 

dzim

Top Contributor
Naja, ohne deinen Code zusehen, würde ich deine letzte Aussage so nicht unterschreiben. Kannst du ein kleines Beispiel zeigen, anhand dessen wir das reproduzieren können? z.B ein kleines Programm, das (Xerial vorausgesetzt) eine DB anlegt, mit Daten füllt und ein zweites, dass es lesen soll und dein beobachtetes Verhalten reproduziert?
Das wäre ein Ansatz. Sonst ist es eher "stochern im Dunkeln"...
 

Paddy.

Aktives Mitglied
Also klein kann das Beispiel ja nicht sein da ich ja größere Anfragen stelle muss. Das Problem kommt ja erst nach ein paar Stunden laufzeit;) Und durch visualvm lässt sich das eindeutig auf die DB-Bibliotek einschränken.
Aber es scheint als lag es an einigen fehlenden close() von PrepardStatements. Diese waren zwar durch den GC vernichtet aber nicht in dem DB-Cache. Zumindens hat dies den Speicher um einiges geschont :)
 

Joose

Top Contributor
Das Problem kommt ja erst nach ein paar Stunden laufzeit;) Und durch visualvm lässt sich das eindeutig auf die DB-Bibliotek einschränken.
Aber es scheint als lag es an einigen fehlenden close() von PrepardStatements.

Wenn es nicht möglich ist ein kleines Beispiel zu basteln, dann wenigstens gröbere Code Ausschnitte wo du Statements absetzt, ResultSet behandelts und die Sachen "angeblich" wieder freigibst.

Aber schön das du selber auf die Lösung gekommen bist :)
 

Paddy.

Aktives Mitglied
Es werden an mehren Stellen ResultSet abgefragt, bei mehren 1000Zeilen Code net so einfach herraus zufinden an welcher Stelle es hackte :D
Ja gottsei dank gefunden war schon am verzweifeln ^^
 

Neumi5694

Top Contributor
Prinzipiell gibt es eigentlich nur 2 Fehlerquellen
a) Du hinterlegst die eingelesenen Daten im RAM und behältst Referenzen darauf, der Speicher wird nicht freigegeben
b) der DB-Treiber hat tatsächlich einen Fehler und frisst immer mehr.
Eventuell kreirst du auch ständig neue Statements, was auch viel Speicher braucht, schließt Resultsets nicht usw.
Schließ sporadisch mal die Verbindung zur DB, um b) auszuschließen. Wenn's dann immer noch passiert, dann ist es wirklich dein Fehler.
 

Ähnliche Java Themen


Oben