OutOfMemory beim Clob

Status
Nicht offen für weitere Antworten.
J

JanB

Gast
Hallo,

da ich mich immer mehr im Kreise drehe, dachte ich mir, frage ich mal die Experten :)

Folgendes Problem:
Aus einer Oracle-Datenbank bekomme ich einen Clob-Wert, welcher per Java in Token zerlegt werden soll und dann per Array als benutzerdefinierter Oracle-Datentyp zurückgegeben wird. Es werden 366.000 Datensätze übermittelt (kann variieren) und bei der Verarbeitung stosse ich wohl an Speichergrenzen, denn 220.000 Datensätze werden problemlos verarbeitet.
Seht ihr eine Möglichkeit diese zu umgehen (z.b. weil ich schlechte Routinen benutze, zuviel Speicher belege (System.gc() an diversen Stelle brachte leider keinen Erfolg) oder mein Ansatz ansich schon falsch ist) oder muss ich eine Speichererweiterung beantragen?

Typen in Oracle:
TYPE TYPE_JAVA_RECORD IS OBEJCT (WERT1 NUMBER, WERT2 NUMBER, ... , WERT26 NUMBER);
TYPE TPYE_JAVA_TABLE IS TABLE OF TYPE_JAVA_RECORD;
-> Ergo nichts anderes als ein 2d-Array.

Clob-Ausschnitt:
  • 1;2923;21.27;20.27;22.82;17.85;6.80;2.46;3.72;3.49;9.99;8.62;20.78;140.81;110.36;104.73;104.33;116.72;168.98;214.95;209.01;233.92;65.01;78.43;97.32;72.54
    1;2924;77.62;77.12;73.24;62.89;59.96;72.26;70.48;148.78;162.29;162.09;186.74;170.70;163.76;181.41;156.67;177.87;185.72;199.78;209.02;173.86;152.53;128.53;105.41;74.79
Dies sind 2 der ca. 360.000 Datensätze.

Java-Quelltext:
Code:
JAVA SOURCE NAMED "Java_Clob_Split" AS
import java.sql.*;
import java.io.*;
import java.util.*;    
import oracle.sql.*;
import oracle.jdbc.*;

public class Java_Clob_Split  
{ 	
    public static String returnJavaTable_String(java.sql.Clob clob_werte, oracle.sql.ARRAY[] arrayout) throws java.sql.SQLException, IOException, java.lang.VirtualMachineError
    {
        int i=0; // Datensatzzaehler

        try {
            // DB-Connection mit Oracle-Server
            DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
            Connection conn = DriverManager.getConnection("jdbc:default:connection"); 

            // Descriptoren für das Mapping der Oracle-Typen
            ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("TYPE_JAVA_TABLE", conn);  
            StructDescriptor struktDescriptor = StructDescriptor.createDescriptor("TYPE_JAVA_RECORD", conn);

            int i_lines = 0; // Anzahl aller Datensaetze (Lines) im Clob
            
            // Durchlauf aller Datensaetze im Clob um die gesammte Datensatzanzahl zu ermitteln (dient der Festlegung 
            // der Array Grenzen)
            if (clob_werte !=null) { 
                Reader is = clob_werte.getCharacterStream(); 
                LineNumberReader lr = new LineNumberReader(is);
                String s = lr.readLine();
                while(s!=null) {
                    i_lines++; // Zaehlen der Datensaetze
                    s=lr.readLine(); // Lesen der naechsten Zeile im Clob
                }
            }

            STRUCT[] datensaetze = new STRUCT[i_lines]; // Speichert alle Datensaetze im Format TYPE_JAVA_TABLE
            int j=0;
            Object[] werte = new Object[26]; // Enthaelt die Werte 1-26 (fuer den Type TYPE_JAVA_RECORD)

            // Auslesen des Clob-Wertes
            if (clob_werte !=null){ 
                Reader is = clob_werte.getCharacterStream(); 
                BufferedReader br = new BufferedReader(is); 


                // ##### Split-Variante 1 (Stream-Tokenizer) ##### 
                StreamTokenizer sToken = new StreamTokenizer(br);
                while (sToken.nextToken() != StreamTokenizer.TT_EOF) {
                    // Falls es sich um einen nummerischen Wert handelt -> uebernehmen und ins Array schreiben
                    if (sToken.nextToken() == StreamTokenizer.TT_NUMBER){
                        werte[j] = new Float(sToken.nval); // Wert 1-26 mit Token fuellen
                        j++ ; // nächster der 26 Werte
                        // falls Wert > 25 wieder Wert 0 des Folgendatensatzes fuellen
                        if (j > 25) {
                            // neuen Datensatz im Array anlegen (TYPE_JAVA_TABLE)
                            datensaetze[i] = new STRUCT(struktDescriptor, conn, werte);
                            j = 0;  
                            i++;
                        }
                    }
                }
            }    
                // ##### Ende Variante 1 ##############                    

            //    ############ Split-Variante 2 (String-Tolenizer #########
            //    String s = br.readLine(); 
            //    while(s!=null){ 
            //        StringTokenizer st = new StringTokenizer(s, ";"); // Trenne den String durch das Trennzeichen ;
            //         while (st.hasMoreTokens()) {
            //             werte[j] = new Float(st.nextToken()); // Wert 1-26 mit Token fuellen
            //             j++;
            //             if (j > 25) {
            //                 datensaetze[i] = new STRUCT(struktDescriptor, conn, werte);
            //                 j = 0;
            //                 i++;
            //             }
            //         } 
            //         s=br.readLine();
            //     } 
            // }
            //     #### Ende Variante 2 ######

            // Rueckgabe-Array an die PL/SQL Funktioon
            arrayout[0] = new ARRAY(descriptor, conn, datensaetze);
            return "Alles ok";
        }
        catch(OutOfMemoryError ee) { 
            return ("Fehler: "+ee + " " +i);
        }
    }	         	         
}

Noch ein paar Anmerkungen zum Code und den Fehlern.
Ich habe den Clob-Wert auf 2 verschiedene Arten versucht zu splitten. Beide Varianten funktionieren auch, solange weniger als ca. 220.000 Datensätze im Clob enthalten sind.

Sind es mehr bekomme ich bei
Variante 1 die Fehlermeldung: ORA-00932: nicht übereinstimmende Datentypen
Variante 2 die Fehlermeldung: java.lang.OutOfMemoryError 224217 (variiert)

Es liegt nicht an den Clob-Werten ansich (also keine Abweichungen der Sturktur ab einem bestimmten Datensatz). Es ist egal, welche 220.000 Datensätze ich auf dem Clob einlese, es treten keine Fehler auf. Nur sobald es weiter über 300.000 sind erhalte ich diese Fehlermeldungen.

Warum ich 2 unterschiedliche Fehlermeldungen erhalte (je nach Splitvariante) ist mir zwar nicht sonderlich klar, müsste aber auf die gleichen Speicherprobleme zurückzuführen sein.

Ich hoffe, mein Problem einigermaßen verständlich vermittelt zu haben und hoffe, ihr könnt mir vllt. ein paar Tipps gehen.

Vielen Dank schonmal an all diejenigen, die sich überhaupt die Mühe machen, sich den Code genauer anzuschauen!

Grüße
Jan
 
J

JanB

Gast
Leider habe ich mich vergessen zu registieren, somit kann ich meinen Post leider nicht mehr editieren.

Oracle Version: 9.1
Java-Version: 1.3.1
 
J

JanB

Gast
Ist das Problem zu speziell oder habe ich Infos vergessen, die wichtig gewesen wären?

Hoffe immer noch auf eine Antwort :)
 
S

SlaterB

Gast
Anregung: wenn du 10. Mio. (360k mal 15) mal Werte wie 121.27 hast,
dann lohnt es sich vielleicht, die zu cachen,

erstelle ein Float-Array der Größe 10.000 mit allen Werte von 0.01 bis 999.99
und nimm Float-Objekte aus diesem Array statt ständig new Float()

---------

verwende

Runtime runtime = Runtime.getRuntime();
long max = runtime.maxMemory();
long free = runtime.freeMemory();
long total = runtime.totalMemory();

um dir generell deine Speicherbelegung anzuschauen,
z..B. alle 1000 Elemente um abzuschätzen, was du pro Datensatz brauchst

und auch zum Zeitpunkt der Exception oder kurz davor (verwendest du nur 64 MB Grundspeicher oder mehr?)
 
J

JanB

Gast
Vielen Dank für die Antwort!

Gleich vorne weg:
Code:
long max = runtime.maxMemory()
-> ist leider erst ab Java-Version 1.4 verfügbar.

Habe also etwas mit freeMemory herumexperimentiert und man konnte gut erkennen, wann der GC in Erscheinung trat. Ein expliziter GC-Aufruf, sobald freeMemory unter einen bestimmten Wert fiel, brachte leider auch nichts.

Die Idee mit den Arrays war gut, aber bei deinem Bespiel enthält es ja bereits 100.000 Elemente (nicht 10.000 ;-)) und ich habe heute erfahren, dass die Werte bis auf 3000 anwachsen können -> ergo 300.000 Elemente.

Hatte nun trotzdem gehofft, dass jetzt der Speicher ausreicht, da 300.000 Array-Elemente (+ ~ 10 Mio Verweise) eigentlich weniger verbrauchen müssten, als ~ 10 Mio Float-Einträge. Aber leider erscheint der OutOfMemory Fehler an ähnlicher Position.

verwendest du nur 64 MB Grundspeicher oder mehr?
Da habe ich gar keine Ahnung. FreeMemory bringt mit zum Start des Programms einen Wert von rund 4 Mio.
Ich arbeite ja direkt auf einer Oracle-Datenbank und lasse mir alle Ergebnisse als "SELECT proc_name FROM dual" zurückgeben.

Andere Ratschläge sind willkommen :meld:
 
S

SlaterB

Gast
wenn dein Programm bisher keinen erhöhten Speicher benutzt,
dann kannst du ihn wahrscheinlich von derzeit 64 auf 512 MB hochsetzen
siehe google oder aktuell hier im Forum
http://www.java-forum.org/de/viewtopic.php?t=53774

falls x00.000 zuviel sind, dann müssen ja nicht alle Werte gecacht werden,
vielleicht gibt es ja eine Konzentration in einem bestimmten Bereich (z.B. unter 200 wie in deinem Beispiel)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Kirby.exe Verwirrung beim Query Datenbankprogrammierung 4
Z Beim schließen des Programms die verbindung zur DB beenden. Datenbankprogrammierung 4
C Oracle Fehler beim list.add() Datenbankprogrammierung 5
L MySQL Bekomme einen Fehler beim ResultSet Datenbankprogrammierung 12
H Brauche Hilfe beim Mappen von 3 Tabellen a 1:n mit hbm.xml. Datenbankprogrammierung 34
J Java Eclipse Hilfe beim Programmieren Datenbankprogrammierung 7
B JPA->fehler beim Insert in die Datenbank Datenbankprogrammierung 3
V Fehler beim Generierung Fehler beim Generierung java.lang.ArrayIndexOutOfBoundsException: 0 Datenbankprogrammierung 12
H HSQLDB Beim öffnen folgender Fehler: ... java.lang.NullPointerException Datenbankprogrammierung 1
S Hibernate-Konfiguration : Unverständliche Ausgabe beim Ausführen Datenbankprogrammierung 0
ruutaiokwu sql server werte swappen beim update-vorgang mit unique-constraints..? Datenbankprogrammierung 2
C H2 Syntax fehler beim erstellen einer Tabelle Datenbankprogrammierung 4
M MySQL probleme beim "Generate Tables from Entities" Datenbankprogrammierung 9
T MySQL Multithreading beim Datenbankzugriff Datenbankprogrammierung 3
T Fehler beim ausgeben von Tabellen Inhalt Datenbankprogrammierung 9
J Datentyp der Spalte beim Datenbankdesign unbekannt Datenbankprogrammierung 12
S Derby/JavaDB Probleme beim anlegen einer embedded DB Datenbankprogrammierung 13
W No data found: SQL-Abfrage funktioniert nur beim Debuggen Datenbankprogrammierung 3
N HSQLDB Problem beim Treiberladen im Jar Datenbankprogrammierung 6
M Problem beim Erstellen einer Query Datenbankprogrammierung 7
M Datenbankverbindung zu langsam beim Insert? Datenbankprogrammierung 6
Paristick MSSQL - JDBC Exception beim Registrieren Datenbankprogrammierung 5
D JDBC Fehler beim laden der nativen Bibliothek db2jcct2 Datenbankprogrammierung 9
S Problem beim Anlegen einer Tabelle Datenbankprogrammierung 5
L Derby/JavaDB Fehler beim Erstellen einer Tabelle Datenbankprogrammierung 2
T Problem beim schreiben von daten Datenbankprogrammierung 4
S MySQL generelles vorgehen beim connect zu entfernter datenbank Datenbankprogrammierung 3
A Derby/JavaDB Probleme beim Einbinden Datenbankprogrammierung 2
L CLOB-Daten werden beim Einfügen in die Datenbank geändert? Datenbankprogrammierung 5
J MySQL Hibernate: Probleme beim Speichern von OneToMany - Datensätzen Datenbankprogrammierung 2
X Vector Verhalten beim DataModel seltsam Datenbankprogrammierung 6
D MySQL Problem beim einfügen von Double-Zahlen Datenbankprogrammierung 4
U MSSQL Verbindung steht, aber meckert beim Statement Datenbankprogrammierung 2
N Probleme beim Aufruf aus der DB Datenbankprogrammierung 7
cosmic Problem beim Update einer Oracle DB Datenbankprogrammierung 7
T Problem beim Update in die Access DB Datenbankprogrammierung 9
F SQLException fangen beim verbinden mit Hibernate Datenbankprogrammierung 17
M Problem beim Importieren einer Datenbank Datenbankprogrammierung 3
C Datenumwandlungsfehler beim Umwandeln Datenbankprogrammierung 4
S Fehler beim Auslesen von Daten Datenbankprogrammierung 6
V Probleme beim Öffnen "einiger" SuperbaseTabellen p Datenbankprogrammierung 8
G Probleme beim Methodenaufruf einer EJB Datenbankprogrammierung 10
H Beim insert bekomme ich den Fehler missing select keyword Datenbankprogrammierung 2
V Fehlermeldung beim Insert Datenbankprogrammierung 16
G beim lesen der db alte daten bekommen? Datenbankprogrammierung 5
A Problem beim Laden des Treibers Datenbankprogrammierung 5
A Fehler beim Starten des Servers für H2 Database Datenbankprogrammierung 13
A Probleme beim Schreiben in eine CSV-Datei aus einer H2-DB Datenbankprogrammierung 2
G Problem beim einfügen in der Datenbank Datenbankprogrammierung 4
G Problem beim Schreiben eines Dateipfads in MySQL-DB Datenbankprogrammierung 9
D An Access Datenbank andocken ohne sie beim System anzumelden Datenbankprogrammierung 3
M "SQL - Apache" Problem beim laden des Applets Datenbankprogrammierung 4
J Fehlermeldung beim ausführeren dieses Befehles Datenbankprogrammierung 5
G Fehler beim Verbinden Datenbankprogrammierung 4
D Problem beim Zugriff auf eine Oracle-DB Datenbankprogrammierung 23
A Datenbankzugriff per Applet - Problem beim Treiber laden Datenbankprogrammierung 6
E Problem beim laden des JDBC Driver bzw der Database Datenbankprogrammierung 8
M Daten von MySQL nach MSSql probleme beim schreiben Datenbankprogrammierung 3
S JDBC-Anfänger und Probleme beim Treiberfinden etc. Datenbankprogrammierung 4
T Probleme beim Verbindungsaufbau zum SQL 2000 Datenbankprogrammierung 2
P Wie Usernamen beim Einloggen für Combobox übernehmen?HELP Datenbankprogrammierung 2
N Fehler beim matchen von Strings via Query Datenbankprogrammierung 2
K MsAccess immer beim zweiten Update java.sql.SQLException Datenbankprogrammierung 28
T Problem beim Update vom Resultset + Firebird Datenbankprogrammierung 2
R JDBC: Resultset beim Thema MEZ&MESZ Datenbankprogrammierung 12
J Fehler beim PreparedStatement Datenbankprogrammierung 2
P Fehlermeldung beim Erstellen einer neuen Tabelle Datenbankprogrammierung 2
M Problem beim erstellen der DB Datenbankprogrammierung 3
G Problem beim Zugriff SQL 2000 Datenbankprogrammierung 2
6 Hilfe beim Einstieg Datenbankprogrammierung 15
A ClassNotFoundException beim Laden des Oracle-JDBC-Treibers Datenbankprogrammierung 10
A Fehler beim Verbinden zur Oracle-DB Datenbankprogrammierung 6
G Rundungsfehler beim Lesen von Fliesskommazahlen... Datenbankprogrammierung 2
K Problem beim Einlesen von Werten aus einem Textfeld Datenbankprogrammierung 11
V Exception beim Speichern von eingegebenen Daten in Tabelle Datenbankprogrammierung 2
W Fehlermeldung beim Ändern einer jdbTable Datenbankprogrammierung 5
G Fehlermeldung beim Zugriff auf SQL-Server-DB Datenbankprogrammierung 3
E Problem beim Datenbank-Design (relational) Datenbankprogrammierung 10
C PostgreSQL CLOB Transport Datenbankprogrammierung 4
V Oracle Umstellung LONG -> CLOB Datenbankprogrammierung 2
AlexSpritze Derby/JavaDB CLOB mit JDO&JPOX + Boolean Datenbankprogrammierung 2
G Inhalt eine Clob Feldes zw. zwei DB's kopieren Datenbankprogrammierung 2
B Java Derby Datenbank mit CLOB & BLOB Datenbankprogrammierung 5
G CLOB to String - Encoding Problem Datenbankprogrammierung 6

Ähnliche Java Themen

Neue Themen


Oben