JavaHeap Error

Status
Nicht offen für weitere Antworten.

elturco

Mitglied
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

Bekanntes Mitglied
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.
 

Wildcard

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

Sanix

Top Contributor
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

Bekanntes Mitglied
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

Top Contributor
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.

Code:
//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:
Code:
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

Bekanntes Mitglied
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

Bekanntes Mitglied
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
Code:
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

Top Contributor
Nimm ne Start.exe oder eine Start.bat. Das sind eigentlich die einfachsten Möglichkeiten um die Xms und Xmx Werte zu setzen.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben