# JavaHeap Error



## elturco (9. Nov 2006)

Hallo zusammen,

ich habe hier einen Code, wenn ich es zum laufen bringen möchte bekomme ich die Fehlermeldung: 

java.lang.OutOfMemoryError: Java heap space

woran kann es liegen`? zu wenig RAM ?


Grüße


----------



## LoN_Nemesis (9. Nov 2006)

java -Xmx32m -Xms32m <ClassName>

Wenn du dein Programm mit Standardparametern startest, ist der Heap nur 2MB gross. Das bedeutet, wenn deine Daten in Speicher insgesamt größer als 2 MB sind, bekommst du die Exception. Mit der obigen Anweisung wird das Limit auf 32 MB erhöht, sollte eigentlich reichen. Kannst du natürlich bei Bedarf noch höher schrauben.


----------



## elturco (9. Nov 2006)

ne dumme Frage aber kannst Du mir mal sagen wo ich das einzugeben habe, benutze Eclipse


----------



## Wildcard (9. Nov 2006)

In der entsprechenden launch configuration hast du die Möglichkeit vm-Parameter anzugeben.


----------



## Sanix (7. Aug 2007)

Ich kriege auch einen Heap Space Error. Leider sehe ich jedoch nicht wo. Meine Exception kommt im Thread main mit der Meldung OutOfMemory...
Ich habe jetzt auch Mal dne Heap Space erhöht. Aber gibt es eine Möglichkeit zu sehen, welche Variable den Speicher überfüllt? Weil der Fehler tritt immer nur nach einer bestimmten Zeit auf. Und bei einer Methode die mittels HttpUnit eine Seite aufruft und diese parst.


----------



## doctus (7. Aug 2007)

lädst du irgendwelche bilder oder sounddateien massenweise ein?

hatte auch mal den error, als ich versucht habe über 200 buffered images  im Speicher zu halten^^


----------



## Illuvatar (7. Aug 2007)

Wenn du mit vielen Bildern hantierst, könnte dir diese Klasse nützlich sein, die ich mal geschrieben habe (auch auf andere Medien übertragbar). Die Klasse ist ein Wrapper um eine SoftReference, d.h., das Bild wird geladen wenn es benötigt wird, und verworfen, wenn der Speicher voll wird. Wenn das Bild gerade (noch) nicht geladen ist, wird ein Platzhalter-Bild zurückgegeben.


```
//package de.illu.zoomviewer;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.ref.SoftReference;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.imageio.ImageIO;

public class ImagePointer implements Runnable
{
    public static final BufferedImage LOADING;
    static {
        LOADING = new BufferedImage(400, 300, BufferedImage.TYPE_INT_ARGB);
        Graphics g = LOADING.getGraphics();
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, 400, 300);
        g.setColor(Color.BLACK);
        g.setFont(new Font("Serif", Font.BOLD, 50));
        FontMetrics fm = g.getFontMetrics();
        String str = "Loading...";
        g.drawString(str, (400 - fm.stringWidth(str)) / 2, 150);
        g.dispose();
    }

    private SoftReference<BufferedImage> image = null;
    private String source = null;

    private AtomicBoolean threadRuns = new AtomicBoolean(false);
    private Thread loadThread;

    public BufferedImage getImage()
    {
        if (image == null || image.get() == null) {
            if (threadRuns.compareAndSet(false, true)) {
                (loadThread = new Thread(this)).start();
            }
            return LOADING;
        } else {
            return image.get();
        }
    }

    public void joinThread() throws IOException
    {
        if (!threadRuns.get())
            return;
        try {
            loadThread.join(10000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("Interrupted while loading Image");
        }
    }

    public void run()
    {
        if (source != null) {
            try {
                InputStream is = ImagePointer.streamFor(source);
                BufferedImage img = ImageIO.read(is);
                image = new SoftReference<BufferedImage>(img);
                img = null;
                is.close();
            } catch (IOException e) {
                // discard
            }
        }
        threadRuns.set(false);
    }

    static InputStream streamFor(String source) throws IOException
    {
        if (source.startsWith("zip:")) {
            int i = source.indexOf('|');
            File file = new File(source.substring(4, i));
            ZipFile zipFile = new ZipFile(file);
            ZipEntry entry = zipFile.getEntry(source.substring(i + 1));
            InputStream is = zipFile.getInputStream(entry);
            return is;
        } else {
            return new FileInputStream(source);
        }
    }

    public String getSource()
    {
        return source;
    }

    public void setSource(String source)
    {
        this.source = source;
        this.image = null;
    }
}
```

Verwendung zum Beispiel:

```
ImagePointer meinBild = new ImagePointer();
//lädt bild.jpg aus C:\testzip.zip. Ohne zip einfach nur den Dateinamen schreiben (siehe streamFor Methode)
meinBild.setSource("zip:C:\\testzip.zip|bild.jpg");
doSomethingWith(meinBild.getImage());
//unbedingt wichtig dass das bild schon geladen ist:
meinBild.getImage();
meinBild.joinThread();
doSomethingWithLoadedImage(meinBild.getImage());
```


----------



## Xams (7. Aug 2007)

Wie lässt sich den bei Jar Dateien der genutzte Arbeitsspeicher erhöhen, d.h. was mus ich in die Manifest Datei schreiben
java -Xmx32m -Xms32m  -jar MeinJar.jar 
Geht okay, ist aber für Endanwender (oder Kunden zu unbequem)


----------



## Apo (7. Aug 2007)

das Problem hatte ich auch schon
Aber in die Manifest Datei kann man nicht reinschreiben, wieviel Speicher genutzt werden soll. Man könnte über den Umweg einer startJar gehen und dann die eigentliche Jar mit 
	
	
	
	





```
public static void main(String[] args) throws IOException {
		Runtime.getRuntime().exec("javaw -jar -Xms32m -Xmx256m meinJar.jar");
	}
```
 aufrufen. Eine bessere Lösung habe ich auch noch nicht gefunden


----------



## Evil-Devil (7. Aug 2007)

Nimm ne Start.exe oder eine Start.bat. Das sind eigentlich die einfachsten Möglichkeiten um die Xms und Xmx Werte zu setzen.


----------

