# viele Datensätze aus Datenbank - Java Heap Space - Excepion



## Oli (19. Nov 2008)

Hallo,

ich lese aus einer Datenbank eine bestimte Anzahl > 10.000 Zeilen ein (10 Spalten).
Das ganze liegt in einer ArrayList, jede Zeile ein StringArray.
Die Daten werden auch geladen, kein Problem aber wenn ich weiter mit den Daten arbeiten will (z.B. auf Labels packen), dann bekomme ich eine:

java.lang.NullPointerException
Exception in thread "Thread-3" java.lang.OutOfMemoryError: Java heap space
	at java.lang.Object.clone(Native Method)
	at java.awt.GridBagConstraints.clone(Unknown Source)
	at java.awt.GridBagLayout.setConstraints(Unknown Source)
	at java.awt.GridBagLayout.addLayoutComponent(Unknown Source)
	at java.awt.Container.addImpl(Unknown Source)
	at java.awt.Container.add(Unknown Source)
	at view.KundenNummer$1.run(KundenNummer.java:134)
	at java.lang.Thread.run(Unknown Source)
Connection closed
Exception in thread "AWT-Windows" 


Nun meine Frage:

Würde sich das Problem lösen lassen wenn ich für jede größere Aktion (also Laden, graphisch aufbereiten usw.) mit einem extra Thread arbeite?
Oder kann man den HeapSpace erweitern?


Grüße Oli


----------



## The_S (19. Nov 2008)

Den Heapspace kannst du mit dem Konsolenparameter -Xms bzw. -Xmx erweitern. Allerdings ist deine Fehlermeldung sehr merkwürdig - eine NullPointerException gekoppelt mit einem OutOfMemoryError!?


----------



## tuxedo (19. Nov 2008)

Heapspace erhöhen ist eine Methode. Daten blockweise aus der DB lesen und verarbeiten so dass nicht _alles_ im Speicher rumliegen muss eine andere ...

Weil, selbst wenn du den Heapspace jetzt erhöhst: Was passiert wenn es auf einmal 20.000 Zeilen werden?! Dann kommst du vermutlich wieder in Schwierigkeiten.


----------



## Oli (19. Nov 2008)

Hi,

ja das stimmt wohl. Nun wie kann ich denn die Daten blockweise aus der Datenbank lesen? Ich hab eine stored proc mit einem dreifach join und die liefert mir eben einen cursor zurück, den ich dann im meine ArrayList speichere.


----------



## Gast (19. Nov 2008)

Wozu in eine ArrayList speichern?


----------



## tuxedo (19. Nov 2008)

Kann ich dir sop spontan auch nicht sagen. Bei MySQL gibts jedenfalls sowas:


```
SELECT *
FROM `mantis_custom_field_project_table`
LIMIT 0 , 30
```

Damit kriegst du nur die ersten 30 Zeilen des SELECT Results.


```
SELECT *
FROM `mantis_custom_field_project_table`
LIMIT 30, 60
```

Und damit dir zweiten 30 ...

- Alex


----------



## Oli (19. Nov 2008)

Es handelt sich dabei um Kundendaten, mit Kundennummer, Anschrift usw.
Diese sollen alle angezeigt werden. Ich habe eine Klasse Kunde, dort wird für jede Kundennummer ein Exemplar erzeugt und auf die ArrayList gepackt.
Ich brauche das um später Berechnungen, weitere selects oder vergleiche laufen lassen zu können. 
Die Daten müssen also immer global verfügbar bleiben.


----------



## The_S (19. Nov 2008)

@tuxedo

wenn Olli aber keinen Einfluss auf die stored procedures hat, dann nützt ihm das wenig ...


----------



## Oli (19. Nov 2008)

Hallo zuxedo,

nun aber ich benötige trotdem alle Datensätze...


----------



## Oli (19. Nov 2008)

Oder hat Java ernsthaft ein Problem, wenn ich 10000 Panels mit jeweis 5 Labels generiere? 
Schaut nämlich fast so aus. Die Zeile in der die exception geworfen wird:

JLabel plz = new JLabel();


----------



## The_S (19. Nov 2008)

Java hat keine Probleme damit. Aber der zur Verfügung stehende Speicher ...

für was musst du denn so viele Labels und Panels und Daten im Arbeitsspeicher halten?


----------



## FArt (19. Nov 2008)

Oli hat gesagt.:
			
		

> Oder hat Java ernsthaft ein Problem, wenn ich 10000 Panels mit jeweis 5 Labels generiere?
> Schaut nämlich fast so aus. Die Zeile in der die exception geworfen wird:
> 
> JLabel plz = new JLabel();



lol

Java hat keinerlei Probleme, so lange du der VM genügend Speicher zuweist. Wenn du davon nicht unbegrenzt zur Verfügung hast, solltest du dir überlegen, ob das was du machst auch sinnvoll ist.

Tipp: es gibt keinen sinnvollen Anwendungsfall für 10000 Panels.


----------



## tuxedo (19. Nov 2008)

>> wenn Olli aber keinen Einfluss auf die stored procedures hat, dann nützt ihm das wenig ...

Wollte damit nur ausdrücken, dass es sicher eine Möglichkeit gibt das Resultset einzuschränken...

>> für was musst du denn so viele Labels und Panels und Daten im Arbeitsspeicher halten?

Und genau das war die Intention zu sagen/schreiben: Blockweise lesen

Gruß
Alex


----------



## Oli (19. Nov 2008)

Hallo FArt,

Eine ScrollPane auf der 10000 Panels liegen und auf diesen Panels liegen dann eben Labels mit Kundennummer usw ist nicht sinnvoll?
Nun wenn der Auftrageber meint es ist sinnvoll und er sich gerne durch 10000 Datensätze manövriert (nun ne Schnellsuche will er natülich auch) dann ist das eben so. 

Ich habs jetzt in eine Tabelle gepackt, gut gefällt mir zwar net so gut, aber es funktioniert erstmal...


----------



## The_S (19. Nov 2008)

Du kannst auch deine bisherige Datenansicht beibehalten. Du zeigst ja eh nicht alle Datensätze gleichzeitig an. Musst dann halt nur beim Scrollen entsprechend reagieren ...


----------



## Oli (19. Nov 2008)

Noch ne Frage:

Insgesamt sind es 800.000 Kunden. Die storedProc liefert abhängig von Benutzer eine Anzahl von Datensätzen. Wenn sich ein Abteilungsleiter einklinkt, dann bekommt er alle Kundendaten seiner Mitarbeiter (10000*12)...

Da hauts mir doch dann die JTable um die Ohren oder? Maximale Zeilenanzahl = 65536 oder?

Grüße Oli


----------



## Oli (19. Nov 2008)

Hallo Hobbit, das ist eine gute Idee. Perfekt, danke (Hätte ich ja auch selbst draufkommen können)...

Grüße Oli


----------



## The_S (19. Nov 2008)

Wie kommst du da drauf?


```
package de.test;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class Test {
	
  public static void main(String args[]) throws Exception {
    
	JFrame frame = new JFrame();
	JTable table = new JTable(100000, 10);
	for (int i = 0; i < 100000; i++) {
		table.setValueAt(i, i, 0);
	}
	frame.add(new JScrollPane(table));
	frame.setVisible(true);
  }
}
```


----------



## tuxedo (19. Nov 2008)

Jupp, solltest die Panels mit dem ganzen Krempel dann "on-the-fly" laden und "alte" Panels die dann nicht mehr sichtbar sind entfernen.


----------



## Oli (19. Nov 2008)

Dachte ich hätte dass irgendwo mal gelesen. Dann hab ich mich getäuscht.
Nun ich werde das nun eh so machen, wie du vorgeschlagen hast. Die Datenbasis habe ich ja und ich muss ja nur eine bestimmte Menge anzeigen. 
Die Lösung mit der erweiterung der Speichers der VM ist ja auch net des wahre. Wer will den ein Prog im Speicher liegen haben, dass mal eben 250 MB groß ist...


----------



## Oli (19. Nov 2008)

Hi tuxedo,

ich dachte mir eigentlich, dass ich eine vorgegeben Anzahl von Panels mit Ihren Labels anzeige und dann eben wenn "gescrollt" wird nur die Labels mit neuen Daten füttere...

Oder ist es besser, jedesmal die Panels und Labels neu zu erstellen? Ist doch eigentlich unnötig und braucht unnötig Rechenleistung, oder?


----------



## FArt (19. Nov 2008)

Oli hat gesagt.:
			
		

> Hi tuxedo,
> 
> ich dachte mir eigentlich, dass ich eine vorgegeben Anzahl von Panels mit Ihren Labels anzeige und dann eben wenn "gescrollt" wird nur die Labels mit neuen Daten füttere...
> 
> Oder ist es besser, jedesmal die Panels und Labels neu zu erstellen? Ist doch eigentlich unnötig und braucht unnötig Rechenleistung, oder?



Du brauchst nur sichtbare Panels. Genau das war gemeint mit "wie sinnvoll sind 10000 Panels", denn sehen kann die niemand... auch deine Kunden nicht.

[EDIT]
Wäre nicht eine JTable das richtige für dich?


----------



## Oli (19. Nov 2008)

Hallo FArt, nun leider kann ich keine Gedanken lesen ;-) 

das mit der JTable habe ich bereits weiter oben beschrieben. Gefällt mir aber nicht so gut. Software hat Anforderungen: Funktionale und nicht-funktionale. Zu den nicht-funktionalen gehört eben: "Es muss gut ausschauen!" - Nun und darauf wird manchmal mehr Wert drauf als auf die Wichtigen... (Leider)
Deswegen: Keine Table, sondern schöne farbige Panels mit runden Ecken usw...

Grüße Oli


----------



## FArt (19. Nov 2008)

Oli hat gesagt.:
			
		

> Hallo FArt, nun leider kann ich keine Gedanken lesen ;-)
> 
> das mit der JTable habe ich bereits weiter oben beschrieben. Gefällt mir aber nicht so gut. Software hat Anforderungen: Funktionale und nicht-funktionale. Zu den nicht-funktionalen gehört eben: "Es muss gut ausschauen!" - Nun und darauf wird manchmal mehr Wert drauf als auf die Wichtigen... (Leider)
> Deswegen: Keine Table, sondern schöne farbige Panels mit runden Ecken usw...
> ...



Nicht Gedanken lesen, sondern nachdenken ;-)
Der gesunde Menschenverstand sagt: das ist nicht sinnvoll... was ist sinnvoll? Obiger Lösungsversuch hört sich sinnvoll an.

Auch eine JTable kann eure Vorgaben erfüllen... mit einem Unterschied: es steckt gleich das richtige Model dahinter und der richtige Controller. Was du machst ist das gleiche noch mal (suboptimal) nachbauen, also ein Rad neu erfinden, aber mit Ecken und Kanten.

[EDIT]
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#renderer


----------



## FArt (19. Nov 2008)

... und wie Jacko schon immer sagte: "you are not alone..."

Die richtige Idee, das richtige Vorgehen und Google und schon findet man z.B. das hier:
http://www.javaworld.com/javaworld/javatips/jw-javatip137.html


----------



## didjitalist (19. Nov 2008)

ein durchaus gängiges verfahren für sowas sind lokale caches, die auf der festplatte des clients verwaltet werden. das ist genau dann nötig, wenn man die daten nur sequentiell anfordern kann und nicht beliebige fenster. bei stored procedures ist das ab und an der fall. klar könnte man auch immer entsprechend durchs result set fetchen und nicht benötigte daten verwerfen, aber wozu die datenbank unnötig belasten?

das problem bei solchen verfahren ist natürlich zu erkennen, wann man seinen cache updaten muss.


----------

