# outOfMemoryError: Java heap space



## dior (1. Aug 2012)

Hallo,

ich habe ein kleines Prog welches knapp mehr als 4 000 000 Datensätze aus deine DB auslieset und diese in ein ResultSet schreibt. Dieses wird dann in einer Tabelle ausgegeben.


```
.
.
.

public static FillTable abfrage() throws Exception{
 
 Connection con = _DB_Connection.getConnection();
 Statement st = con.createStatement();
 System.out.println("Start der SQL Abfrage...");
 
 ResultSet rs = st.executeQuery("SELECT ...........");

 FillTable model = new FillTable(rs);
 return model;
  
 }
```

allerdings komme ich anscheinend an die Grenzen des Heap Speichers...



> Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
> at java.math.BigInteger.stripLeadingZeroBytes(BigInteger.java:2842)
> at java.math.BigInteger.<init>(BigInteger.java:237)
> at oracle.jdbc.driver.NumberCommonAccessor.getBigDecimal(NumberCommonAccessor.java:2734)
> ...



Wie kann ich hier das Problem lösen?   (bis ~ 1000000 Datensätze ist es kein Problem)


----------



## SlaterB (1. Aug 2012)

MySQL JDBC Memory Usage on Large ResultSet  Ben J. Christensen


----------



## Landei (1. Aug 2012)

Man kann sich das Ergebnis in mehreren "Chunks" holen (bei mysql geht das mit LIMIT und OFFSET, keine Ahnung, ob das Standard-SQL ist).


----------



## dior (1. Aug 2012)

Es handelt sich um Oracle...

so, ich habe jetzt st.setFetchSize(Integer.MIN_VALUE); eingebaut bekomme aber die Meldung:



> Schwerwiegend: null
> java.sql.SQLException: Ungültige Argumente in Aufruf: setFetchSize
> at oracle.jdbc.driver.OracleStatement.setPrefetchInternal(OracleStatement.java:2884)
> at oracle.jdbc.driver.OracleStatement.setFetchSize(OracleStatement.java:4156)
> at oracle.jdbc.driver.OracleStatementWrapper.setFetchSize(OracleStatementWrapper.java:246)


----------



## SlaterB (1. Aug 2012)

probier mal paar andere Werte als diesen ungewöhnlichen, der im Link vorgeschlagen wird

https://hibernate.onjira.com/browse/HHH-682


> Oops, found by decompiling Oracle driver:
> 
> /1726/ if(i < 0 || i > 32767)
> /1727/ DBError.throwSqlException(68, "setFetchSize");
> ...


----------



## maki (1. Aug 2012)

Vielleciht hab  ich was übersehen, aber wo schliesst du die Connection bzw. das ResultSet wieder?


----------



## jwiesmann (1. Aug 2012)

du kannst dein Statement (bei Oracle ist es ziemlich schäbig) wie folgt umbauen:

```
select * from ( DEIN_STATEMENT ) where rownum < 1000;
// das nächste wäre dann 
select * from ( DEIN_STATEMENT ) where rownum >= 1000 and rownum < 2000;
// usw.
```
Leider ist die Oracle-DB nicht so schlau wie MySql oder eigentlich alle Datenbanken die ich kenne und kann mit einem limit oder offset umgehen.
Für Skeptiker ... das rownum muss um das eigentliche Statement herumgebaut werden, da oracle sonst nur 1000 Datensätzen holt und diese dann sortiert. Somit kann es sein, dass man bei der nächsten Abfrage identische oder ganz andere Daten bekommt ...

Edit:
Aber mal eine andere Frage:
Wer in will sich eine Tabelle mit > 4.000.000 Datensätze angucken? Vielleicht solltest du ein Paging oder sowas einbauen .. sonst ist es ja total unübersichtlich


----------



## dior (1. Aug 2012)

Danke für eure Antworten...

das mit der FetchSize hab ich noch immer nicht ganz verstanden und hinbekommen, aber das mit der Aufteilung auf mehrere Queries und der rownum ist eine machbare Lösung....



> Wer in will sich eine Tabelle mit > 4.000.000 Datensätze angucken? Vielleicht solltest du ein Paging oder sowas einbauen .. sonst ist es ja total unübersichtlich


Gebe ich dir recht... ich gebe es in einer Tabelle aus die ich Filtern und sortieren kann. Damit bekommt man dann gleich eine Übersichtlicherer ansicht


----------



## bone2 (1. Aug 2012)

üblicherweise schickt man mit filter/sortierung nen neuen query ab und buffert nicht die ganze db in das programm um dann dort zu sortieren und zu filtern.


----------

