Problem mit BufferedImages und ram verbrauch

Status
Nicht offen für weitere Antworten.

nebu

Mitglied
Hallo,
ich hab zur zeit folgendes Problem:

Ich Vergröße druch drücken eines buttons ein BufferedImage um einen bestimmten Faktor.
Der Faktor ist dabei immer +5% oder -5%.
Für das Vergrößern benutze ich folgende Methode:

Code:
private void resize(double zoom)
{
	if (orgImage == null)
		return;
		
	AffineTransform tx = new AffineTransform();
	tx.scale(zoom, zoom);
	AffineTransformOp op = new AffineTransformOp(tx,AffineTransformOp.TYPE_BILINEAR);
	
        flush(resizeImage);
	
	resizeImage =  op.filter(orgImage, null);
}

private void flush(Image image)
{
	if (image != null)
	{
		image.flush();
		image = null;
	}
}

Bei der Zeile "resizeImage = op.filter(orgImage,null);" vergrößert sich der Ram verbrauch ziemlich heftig und teilweise fast garnicht bzw. er vergrößert sich immer zwischen 0.0xxx MB und 7 MB Ram.

Was mich halt nun Wundert ist das er den Platz für das alte Image, was ich wieder auf null setze, nie frei gibt. Es ist auch egal ob das Bild nur noch paar pixel groß ist oder dreimal so groß wird wie am Anfang er addiert immer den 0.0xxxMB-7MB verbrauch hinzu bis ich eine
Exception occurred during event dispatching:
java.lang.OutOfMemoryError: Java heap space
bekomme.

Weiss jemand woran das liegen könnte ?

Es ist auch egal ob ich jre 5 oder 1.4.2 benutze.

PS: Ich hoffe der Thread gehört hier rein ins AWT, Swing & SWT Forum sonst bitte ins richtige Forum verschieben
 
Mglw. hast du noch andernorts Referenzen auf "alte" Instanzen? Die vergisst man gerne mal in einer Map und da bietet sich oft eine WeakHashMap an...
 
hmmmm das mit PhantomReferenz hat mir einen kleinen fehler gezeigt aber sonst werden die Objekte eigentlich alle vom GC gelöscht.
 
Hier ist mal der Dialog.
Ich habe ein PNG Bild dafür genommen welches die masse 1280x960 hat und 50kb groß ist.

Code:
package dialog;

import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JToolBar;

public class PreviewDialog extends JDialog
{
	private static final long serialVersionUID = 1L;
	
	private BufferedImage orgImage;
	private BufferedImage resizeImage;
	
	public int scaleX = 100;
	public int scaleY = 100;
	
	private long start = 0;
	private long end = 0;
	
	public PreviewDialog(JFrame frame, String title, boolean modal)
	{
		super(frame, title, modal);
		
		this.setResizable(false);
		this.setSize(600, 400);
		createComponents();
	}
	
	public void createComponents()
	{
		JToolBar toolBar = new JToolBar();
		toolBar.setFloatable(false);

		toolBar.add(new smallerAction("-"));
		toolBar.add(new biggerAction("+"));

		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(toolBar, BorderLayout.NORTH);
	}
	
	private void resizeImage()
	{
		resize(scaleX / 100.0);
		
		end = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
		double erg = (end-start) / 1000000d;
		System.out.println("Nach Resize: "+erg+" MB");
	}

	public void flush(Image image)
	{
		if (image != null)
		{
			image.flush();
			image = null;
		}
	}

	private void resize(double zoom)
	{
		if (orgImage == null)
			return;
		
		AffineTransform tx = new AffineTransform();
		tx.scale(zoom, zoom);
		AffineTransformOp op = new AffineTransformOp(tx,AffineTransformOp.TYPE_BILINEAR);
		
		flush(resizeImage);
		
		start = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
		resizeImage = op.filter(orgImage, null);
	}
	
	
	class smallerAction extends AbstractAction
	{
		private static final long serialVersionUID = 1L;
		
		public smallerAction(String name)
		{
			super(name);
			putValue(AbstractAction.SHORT_DESCRIPTION, "");
		}

		public void actionPerformed(ActionEvent e)
		{
			scaleX -= 5;
			scaleY -= 5;
			resizeImage();
		}
	}

	class biggerAction extends AbstractAction
	{
		private static final long serialVersionUID = 1L;
		
		public biggerAction(String name)
		{
			super(name);
			putValue(AbstractAction.SHORT_DESCRIPTION, "");
		}

		public void actionPerformed(ActionEvent e)
		{
			scaleX += 5;
			scaleY += 5;
			resizeImage();
		}
	}
	
	public void setImage(BufferedImage image)
	{
		orgImage = image;
	}
	
	public static void main(String[] args)
	{
		try
		{	
			BufferedImage image = ImageIO.read(new File("C:\\HeapTest.png"));
			PreviewDialog pd = new PreviewDialog(null,"title",false);
			pd.setImage(image);
			pd.setVisible(true);
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}
}
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben