MySQL Speicher wird nicht freigegeben bei Datenbankabfragen

sebix

Mitglied
Hallo Zusammen,

ich habe hier ein Problem, dass ich nicht ganz verstehe.

Ich habe folgendes Programm:

Java:
public class DirCrawler {
    static Connection con2;
    static Statement stmt2;
    static ResultSet rs2;
    static String directory, user, pw, server, database, fileconsole;
    static File startdir;
    static File appdir;
    static DIRSlicer slicer = new DIRSlicer();
    static int filecount=0;
    static String partpath;

    
    private static void readconfig(){
        
        Properties properties = new Properties();
        BufferedInputStream stream;
        try {

        stream = new BufferedInputStream(new FileInputStream(startdir.getPath()+"/config.ini"));
        
        properties.load(stream);
        stream.close();
        
        server = properties.getProperty("server");
        user = properties.getProperty("user");
        pw = properties.getProperty("pw");
        directory = properties.getProperty("dir");
        database = properties.getProperty("database");
        fileconsole = properties.getProperty("fileconsole");
        
        
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    
    }


    public static void FileEntry(Path path) {
        
        try {
            
            
        Class.forName("com.mysql.jdbc.Driver");

        filecount++;
        
        con2 = DriverManager.getConnection("jdbc:mysql://"+DirCrawler.server+"/"+DirCrawler.database+"?user="+DirCrawler.user+"&password="+DirCrawler.pw);
        
        stmt2 = con2.createStatement();
        
        rs2 = stmt2.executeQuery("SELECT * FROM `absolut_path` WHERE `filepath` = \""+path+"\"");
        
        if(rs2.next()){
            
            System.out.println("Vorhandene Dateien: " + filecount);
            

        } else {
            
//            slicer.slicer(path, false);
            
        }
        
        con2.close(); 
        stmt2.close();
        rs2.close();
    
        
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
            System.out.println(e.toString());
        }
        
    
        
    }
    
        
        
    
    
    private static void crawler(final Path start) throws IOException {
        // crawl directory and sub-directories
        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
            
            
            @Override
            
            public FileVisitResult visitFileFailed(Path file,
                    IOException exc) {
                System.err.println(exc);
                return FileVisitResult.CONTINUE;
                }
            
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
                throws IOException
            {
    
                File[] files = dir.toFile().listFiles();
               
                if (files != null) { // Erforderliche Berechtigungen etc. sind vorhanden
        
                    for (int i = 0; i < files.length; i++) {
        
                    
                      if (files[i].isDirectory()) {
                          
                       }
                    
                    else {

                        partpath=files[i].toString().substring(3);
                        
                        if(partpath.indexOf("\\")<0){
                            
                            System.out.println("Datei im Laufwerksroot werden nicht berücksichtigt");
                            
                        } else {                       
                        
                        if(partpath.substring(0, 1).equals("$")){
                            
                            System.out.println("Systemverzeichnis wird übersprungen!");
                        }
                        
                        else {
                            
                        FileEntry(files[i].toPath());
                        
                        }
                        
                        }
                          
                    }
                  }
                  
                  
                  
                }
    
                
                return FileVisitResult.CONTINUE;
    
            
            }
        });
        
                
        WatchDir watcher = new WatchDir();
        watcher.processEvents();
    
    
    }
    
    
    
    
    
        
    public static void init(Class<?> mainClass) {
        
//        System.out.println("Starte Verzeichnisermittlung");
        
        String userdir = System.getProperty("user.dir");
        startdir = new File(userdir);

        String mainResName = mainClass.getSimpleName()+".class";
        URL mainRes = mainClass.getResource(mainResName);

        
        
        if(!mainRes.getProtocol().equals("jar")) {
          // don't know what to do. use startdir.
          appdir = startdir;
          return;
        }


        
        String mainLocator = mainRes.getPath();
        String jarpart = mainLocator.substring(0,
            mainLocator.lastIndexOf("!/"));
        File jarfile;

        
        try
        {
          jarfile = new File(new URI(jarpart));
          appdir = jarfile.getParentFile();
        }
        catch(URISyntaxException ex)
        {
          // should not happen. actually.
          Logger.getLogger(DirectoryManager.class.getName()).log(
              Level.SEVERE, null, ex);
          appdir = startdir;
        }


    }
    
    
    
    public static void main(String[] args) throws IOException {
        init(WatchDir.class);
        readconfig();

        if (fileconsole.equals("true")){

            File file = new File(startdir+"/java.log");
        
            try {
            System.setOut(new PrintStream(new FileOutputStream(file,true)));
            } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        }

        Path dir = Paths.get(directory);
        crawler(dir);
        
        }
    }

Das Programm prüft, ob eine bestimmte Datei schon in einer Datenbank enthalten ist. Wenn dem nicht so ist, schreibt es sie rein. Das passiert in einer separaten Klasse (DirSlicer).

Mein Problem ist, dass das Programm Unmengen an Speicher frisst. Bei einem Verzeichnisbaum mit ca. 3.000 Dateien bin ich nach dem Durchlauf bei ca. 200 MByte Speicher, die belegt werden.

Dieser Speicherverbauch resultiert aus der Methode FileEntry soweit konnte ich es eingrenzen. Warum diese Methode so viele Ressourcen frisst ist mir allerdings nicht klar. Zur Eingrenzung habe ich das Aufrufen der Klasse "DirSlicer" deaktiviert, die Ressourcen werden nicht dort verbraucht.

Es wird eine Verbindung aufgebaut, ein Statment erzeugt, ein Resultset geladen. Am Ende der Methode wird das alles wieder geschlossen. Damit müssten doch die Ressourcen wieder freigegeben werden, oder?

Hat jemand eine Idee?

Viele Grüße,
Sebix
 
Zuletzt bearbeitet:

Thallius

Top Contributor
Ich würde den DB Connect aus der Schleife rausnehmen und nur einmal vorher aufmachen und ganz am Ende schließen und dann mal schaun wie es mit dem Speicher aussieht.

Gruß

Claus
 

sebix

Mitglied
Hallo Thallius,

danke für die Antwort. Das hat den Ressourcen-Verbrauch schonmal deutlich reduziert. Ich denke ich mache aber immer noch etwas falsch.

Beispiel an anderer Stelle:

Java:
    public void synversionermitteln(){
        
        
        
        try {
            
            

            stmt2 = DirCrawler.con2.createStatement();
            
            rs2 = stmt2.executeQuery("SELECT * FROM `sync___version`");
            
            if (rs2.next()){
            rs2.last();
            id_sync_version = rs2.getInt(1) + 1;
            } else {
                
                System.out.println("Kein Resultset aus sync_version");
                
            }
            
            
            rs2.close();
            stmt2.close();
            
            
            
            } catch (SQLException e) {
                e.printStackTrace();
                System.out.println(e.toString());
            }
            
            
        
    
    }

Diese Methode allein verbraucht bei ca. 20 - 30 Aufrufen etwa 170 MB Speicher, der sich Stück für Stück aufbaut. Die Tabelle Sync_Version hat allerdings auch 115.000 Einträge. Da hat jedes Resultset auch ein wenig Gewicht, das sollte aber (sobald es geschlossen ist) kein Problem mehr sein, oder?

Ich hoffe Du kannst da Licht in meine Dunkeheit bringen. ;)

Viele Grüße,
Sebix
 
Zuletzt bearbeitet:

Thallius

Top Contributor
Also zunächst mal macht man kein SELECT * sondern gibt die Spalten an die man braucht.

Weiterhin ist es ja auch nicht Sinn einer Datenbank immer alle Datensäötze abzufragen, sondern nur die die man braucht oder sich die Infos von der DB selber aufbereiten zu lassen, so das man nur zurück bekommt was nötig ist.

Da ich nicht weiß was Du eigentlich mit Deinem Code erreichen willst kann ich da nicht helfen.

Der Rest ist halt das Problem von Java. Du hast keinen Einfluss auf den Speicher. Wenn du erstmal 115000 Datensätze gelesen hast, dann sind die im Speicher und wann der Speicher tatsächlich wieder freigegeben wird entscheidet einzig und alleine der Garage-Collector. Darauf hast Du keinen Einfluss. Wenn Du Deiner JVM also 2GB zur Verfügung stellst, dann werden die mit Deinem augenblicklichen Code auch gnadenlos ausgereizt.

Gruß

Claus
 

sebix

Mitglied
Hi Thallius,

nachdem ich bemerkt habe, dass diese Funktion so Speicherhungrig ist, habe ich es schon eingegrenzt. Ziel des Programms ist es, den letzten Eintrag aus der Tabelle zu lesen. Aber ich glaube mit Limit und Order BY kann ich das noch deutlich eingrenzen.

Würde Java den nicht gebrauchten Speicher denn wieder freigeben, wenn ein anderes Programm ihn benötigen würde?

Danke für Deine Hilfe.

Viele Grüße,
Sebix
 

sebix

Mitglied
Hi Claus,

ich habe bisher im Code (da ich nie mit großen Datenmengen gearbeitet habe) nicht sehr auf Optimierung von SQL-Abfragen geachtet. Habe nun nochmal alles durchgeprüft und etliche SQL-Abfragen optimiert und damit den Speichervebrauch um 90% reduzieren können.

:)

Daher nochmal: Vielen Dank!

Sebastian
 

Thallius

Top Contributor
Hi Sebastian,

ich kann nur jedem empfehlen, bevor er mySQL benutzt sich das Buch MySQL von Gallileo Computing zu besorgen und es durchzulesen. Dabei lernt man soviele so wichtige Dinge, wie eben was so eine DB überhaupt kann, wie wichtig es ist die Tabellen ordentlich zu normalisieren und und und. Das ist wirklich sehr gut investiertes Geld und ich habe es an 3 Abenden auf der Couch verschlungen.

Gruß

Claus
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S MySQL Nach wiederholtem Update falsche Werte (im Speicher?) Datenbankprogrammierung 1
B Bei Abfrage schießt der Speicher in die Höhe Datenbankprogrammierung 6
MU5T4NG Datum mit Hibernate in Datenbank speicher Datenbankprogrammierung 2
D SQL-Tabelle nur bis 259 Einträge - oder zuwenig Speicher? Datenbankprogrammierung 3
W Hibernate: Komplette Datenbank in Speicher laden? Datenbankprogrammierung 5
D JOIN COLUMN wird nicht genommen Datenbankprogrammierung 2
Maxim6394 JPA / EclipseLink - n:m Beziehung wird nicht aktualisiert Datenbankprogrammierung 0
Maxim6394 JPA 3.2 & SQLite - LocalDateTime wird falsch geladen Datenbankprogrammierung 1
D Ich möchte dass ich nachdem man den Kommentar geschrieben hat den Kommentar in den Tabelle Bestellübersicht geschbeichert wird klappt nicht bei mir Datenbankprogrammierung 2
Watsoon Treiber wird in Intellij nicht geladen Datenbankprogrammierung 2
Kirby.exe PreparedStatement wird nicht ausgeführt Datenbankprogrammierung 5
Z Datenbank Choicebox wird nicht befüllt Datenbankprogrammierung 15
N Sqlite DB mit Java wird auf Linuxsystem nicht gefunden Datenbankprogrammierung 9
J Netbeans 11 und Eclipse JPA 2.5 Entity wird nicht gefunden Datenbankprogrammierung 4
F H2 ObjectOptimisticLockingFailureException wird nicht geworfen Datenbankprogrammierung 0
S sun.jdbc.odbc.JdbcOdbcDriver wird nicht gefunden Datenbankprogrammierung 2
D MySQL Eingabe wird nicht übernommen... Datenbankprogrammierung 11
L Select Anweisung wird falsch interpretiert Datenbankprogrammierung 3
F sun.jdbc.odbc.jdbcodbcdriver wird nicht gefuden Datenbankprogrammierung 3
E Nur der letzte Datensatz wird in Tabelle geschrieben Datenbankprogrammierung 4
L JTable-DB: Letzter wert wird nicht angezeigt. Datenbankprogrammierung 0
K Datenbank wird bei Programmstart als .jar nicht mehr befüllt Datenbankprogrammierung 12
T MySQL Datetime wird auf Sekunden gerundet, soll es aber nicht Datenbankprogrammierung 2
N SQL-Statement Auslesen des Resultset wird immer langsamer Datenbankprogrammierung 6
P JSF + H2 + TomEE + Hibernate/JPA Datenbank wird nicht angelegt Datenbankprogrammierung 3
C Programm wird nach DB-Eintrag nicht weitergeführt Datenbankprogrammierung 5
M OutOfMemoryException obwohl nur 1 Eintrag abgefragt wird Datenbankprogrammierung 7
T f:event preRenderView Trigger wird nicht ausgeführt Datenbankprogrammierung 4
P Oracle Hibernate - Oracle-VarChar-Index wird nicht genutzt Datenbankprogrammierung 3
A MySQL Datensatz wird nicht richtig gelöscht Datenbankprogrammierung 6
H Microsoft Access Treiber wird nicht gefunden Datenbankprogrammierung 9
S JPA, Primary Key wird nicht in relationstabelle erstellt Datenbankprogrammierung 3
B MySQL Hibernate (duplicate Entry) Beziehungstabelle wird nicht befüllt Datenbankprogrammierung 8
N batchupdate, es wird nur der letzte Eintrag eingetragen Datenbankprogrammierung 5
N batch-Update wird nicht durchgeführt Datenbankprogrammierung 2
M Rückgabewert aus DB wird falsch gelesen Datenbankprogrammierung 3
S Wie überprüfe ich ob die Instanz einer Connection gerade werwendet wird? Datenbankprogrammierung 4
C DB.Treiber wird nicht gefunden? Datenbankprogrammierung 5
E MySQL Treiber wird nicht geladen Datenbankprogrammierung 5
K org.gjt.mm.mysql.driver wird nicht gefunden Datenbankprogrammierung 11
T Unerwartete Datenbankausgabe bei "select now()" (es wird ein .0 angehängt) Datenbankprogrammierung 5
N Ubuntu 9.04 jdbc connector wird nicht gefunden Datenbankprogrammierung 5
K Wird auf den Eintrag referenziert? Datenbankprogrammierung 4
J SqlConnection Instanz wird immer grösser? Datenbankprogrammierung 2
I Sql Befehl wird nicht ausgeführt Datenbankprogrammierung 8
sparrow [Hibernate] Relation wird nicht gespeichert (Topic changed) Datenbankprogrammierung 11
A REVOKE wird nicht durchgeführt Datenbankprogrammierung 2
M Treiber wird nicht gefunden Datenbankprogrammierung 5
P Datenbank wird nicht geschlossen - problematisch? Datenbankprogrammierung 2
N mysql.jdbc treiber wird nicht gefunden Datenbankprogrammierung 2
D Neuer Query wird nicht erkannt Datenbankprogrammierung 10
S JOptionPane wird nicht angezeigt Datenbankprogrammierung 5
W Nur ein Datensatz wird angezeigt, obwohl mehrere existieren Datenbankprogrammierung 7
ven000m SQL Querry wird nicht abgesetzt, da vorher underlined! Datenbankprogrammierung 8
D "Distinct" wird nicht ausgeführt Datenbankprogrammierung 8
H mySql Connector/J Treiber wird nicht gefunden Datenbankprogrammierung 2
C SQLException wenn String auf VARCHAR geschrieben wird Datenbankprogrammierung 10
H JDBC-Treiber wird nicht geladen Datenbankprogrammierung 2
L SQL-Problem: Insert wird nicht ausgeführt Datenbankprogrammierung 5
N Cloudscape wird opensource :) Datenbankprogrammierung 3
X Verbindung zu DB wird zurückgewiesen Datenbankprogrammierung 8
H letzter Datensatz wird nicht gefunden? Datenbankprogrammierung 6
W MySQL-Connector funktioniert nicht über WLAN -> MacOS Datenbankprogrammierung 10
M Meine Datenbank lässt sich mit meiner Methode nicht ändern Datenbankprogrammierung 1
P Reicht finally nicht um DB connections zu schließen in (altem) Java? Datenbankprogrammierung 4
J SQLite Abfrage fehlerhaft - komme nicht weiter - please help. Datenbankprogrammierung 3
M Datenbank Zugraff nach Umwandlung in .jar-Datei nicht mehr möglich Datenbankprogrammierung 4
Auf MySql Datenbank zugreifen funktioniert nicht Datenbankprogrammierung 8
A Java DB Server lässt sich nicht starten Datenbankprogrammierung 3
B SQlite Datenbank, trotz Statements wurden nicht alle Zeilen erzeugt? Datenbankprogrammierung 35
T Datenzeilen werden nicht gelöscht Datenbankprogrammierung 6
Warum funktioniert MySQL nicht Datenbankprogrammierung 8
S Das printen der Ausgabe des Oracle-SQL-Statements in der Java-Eclipse-Konsole funktioniert nicht Datenbankprogrammierung 6
S Datenbankprogrammierung in Java unter NetBeans 12 funktioniert nicht! Datenbankprogrammierung 1
pkm PostgreSQL Kann mit mybatis einen Parameter für eine postgreSQL-Abfrage nicht übergeben. Datenbankprogrammierung 5
Davee SQLite SQLite Datenbank lässt sich nicht auf anderen PCs öffnen Datenbankprogrammierung 8
rafi072001 MicroServices EurekaClient findet anderern EurekaClient nicht Datenbankprogrammierung 1
D JPA gleiche methode funktioniert an einer Stelle, an der anderen nicht Datenbankprogrammierung 3
pkm PostgreSQL Auf eine Spalte kann aus einem Teil der SQL-Aussage nicht zugegriffen werden Datenbankprogrammierung 3
G MySQL JDBC Metadaten auslesen aus .accdb -> Primärschlüssel manchmal erkannt manchmal nicht Datenbankprogrammierung 3
C MySQL SQL Statement wir nicht ausgeführt Datenbankprogrammierung 11
pkm Tomcat Classloader findet bei JPA-Persistierung die Persistence Unit nicht. Datenbankprogrammierung 11
F Tabellen automatisch erstellen wenn sie nicht existieren Datenbankprogrammierung 6
J Java fügt Datensätze ein aber diese werden nicht richtig abgefragt Datenbankprogrammierung 3
J Firebase KeepSynced funktioniert nicht Datenbankprogrammierung 0
OnDemand MySQL Trigger löst nicht aus bei Hibernate Update Datenbankprogrammierung 12
R HSQLDB ResultSet update aktualisiert DB, aber nicht das ResultSet Datenbankprogrammierung 2
platofan23 MySQL Java Programm findet Treiber für mySQL auf Debian-Server nicht? Datenbankprogrammierung 11
B MySQL Data Tools Plattform - "Database Connections" findet den Treiber nicht Datenbankprogrammierung 1
OnDemand One to Many bekomm es nicht hin Datenbankprogrammierung 7
L SQL-Statement INSERT INTO ON DUPLICATE KEY UPDATE funktioniert nicht Datenbankprogrammierung 5
OnDemand Update auf Mysql läuft nicht durch Datenbankprogrammierung 30
R jdbc-Zugriff Nicht erlaubt ? Datenbankprogrammierung 16
R findet Derby.DB nicht !? Datenbankprogrammierung 5
I Datenbankverbindung Oracle DB klappt nicht - getConnection returned null Datenbankprogrammierung 8
X SQLite SQLite Programm beendet/führt nicht weiter aus Datenbankprogrammierung 12
P LDAP: Daten eintragen funktioniert nicht Datenbankprogrammierung 7
Ananaskirsche Datenbanktreiber kann nicht geladen werden Datenbankprogrammierung 2
U Kann die Tabellen nicht finden Datenbankprogrammierung 0
M Java Datenbankanbindung funktioniert nicht Datenbankprogrammierung 4

Ähnliche Java Themen

Neue Themen


Oben