Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Memory leak somewhere. I have no idea.

memory leak

Best Answer wim DC, 12 May 2014 - 06:50 AM

Issue was solved on SO.
Solution was to not initialize the Font variables on every paint call. Go to the full post


This topic has been archived. This means that you cannot reply to this topic.
4 replies to this topic

#1 Chall

Chall

    CC Addict

  • Senior Member
  • PipPipPipPipPip
  • 349 posts

Posted 11 May 2014 - 08:09 PM

Making game, haz memory leak, dunno where except for the method. Never had this happen before, you guys got any ideas?

 

And I know it's a memory leak because when you run the program, the memory just keeps climbing, and doesn't stop.

 

My GUESS is that it has something to do with the BufferedImages, or the method used to retrieve them from the ImageCache. It definitely is somewhere in this method, or any of the methods that it invokes.

 

If you DO find the problem, you have my everlasting thanks. :D

 

Here's the problem method:

public void drawFrame(Graphics2D g) {
		// Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		int width = CLIENT.GAMEFRAME.getBounds().width;
		int height = CLIENT.GAMEFRAME.getBounds().height;
		g.setColor(Color.BLACK);
		Font font1 = null;
		Font font2 = null;
		try {
			font1 = Font.createFont(Font.TRUETYPE_FONT, new File(
					"./cache/fonts/Minecraftia.ttf"));
			font2 = Font.createFont(Font.TRUETYPE_FONT, new File(
					"./cache/fonts/SF Automaton Extended.ttf"));
			g.setFont(font1.deriveFont(15f).deriveFont(Font.BOLD));
		} catch (FontFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (CLIENT.user.loggedIn) {
			g.drawImage(images.getPermaImage(3), width - 520, height - 94, null);
			g.drawImage(images.getPermaImage(2), width - 518, height - 92, null);
			// Skills
			g.drawImage(images.getPermaImage(0), width - 516, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 466, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 416, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 366, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 316, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 266, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 216, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 166, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 116, height - 90, null);
			g.drawImage(images.getPermaImage(0), width - 66, height - 90, null);
			g.drawImage(images.getPermaImage(4), 0, height - 290, null);
			g.drawString(CLIENT.user.name + ": " + CLIENT.user.message, 8,
					height - 48);
		} else {
			g.drawImage(
					images.getPermaImage(5),
					(this.getWidth() - images.getPermaImage(5).getWidth(null)) / 2,
					(this.getHeight() - images.getPermaImage(5).getHeight(null)) / 2,
					null);
			g.drawImage(images.getPermaImage(7), ((this.getWidth() - images
					.getPermaImage(7).getWidth(null)) / 2) + 136,
					((this.getHeight() - images.getPermaImage(7)
							.getHeight(null)) / 2) - 106, null);
			if (!CLIENT.box1Active) {
				g.drawImage(
						images.getPermaImage(6),
						((this.getWidth() - images.getPermaImage(6).getWidth(
								null)) / 2) - 80,
						((this.getHeight() - images.getPermaImage(6).getHeight(
								null)) / 2) - 106, null);
			} else {
				g.drawImage(
						images.getPermaImage(9),
						((this.getWidth() - images.getPermaImage(6).getWidth(
								null)) / 2) - 80,
						((this.getHeight() - images.getPermaImage(6).getHeight(
								null)) / 2) - 106, null);
			}
			if (!CLIENT.box2Active) {
				g.drawImage(
						images.getPermaImage(6),
						((this.getWidth() - images.getPermaImage(6).getWidth(
								null)) / 2) - 80,
						((this.getHeight() - images.getPermaImage(6).getHeight(
								null)) / 2) - 50, null);
			} else {
				g.drawImage(
						images.getPermaImage(9),
						((this.getWidth() - images.getPermaImage(6).getWidth(
								null)) / 2) - 80,
						((this.getHeight() - images.getPermaImage(6).getHeight(
								null)) / 2) - 50, null);
			}

			g.drawImage(
					images.getPermaImage(11),
					((this.getWidth() - images.getPermaImage(10).getWidth(null)) / 2) + 180,
					((this.getHeight() - images.getPermaImage(10).getHeight(
							null)) / 2) - 50, null);
			g.setColor(Color.GREEN);
			g.setFont(font2.deriveFont(18f));
			g.drawString("LOG-IN", ((this.getWidth() - images.getPermaImage(10)
					.getWidth(null)) / 2) + 205, ((this.getHeight() - images
					.getPermaImage(10).getHeight(null)) / 2) - 18);
			g.setColor(Color.BLACK);
			g.setFont(font1.deriveFont(30f).deriveFont(Font.BOLD));
			g.drawString(
					CLIENT.user.usernameBox,
					((this.getWidth() - (CLIENT.user.usernameBox.length() * 1)) / 2) - 225,
					((this.getHeight()) / 2) - 95);
			g.drawString(
					CLIENT.user.passwordBox,
					((this.getWidth() - (CLIENT.user.usernameBox.length() * 1)) / 2) - 225,
					((this.getHeight()) / 2) - 39);
			if (CLIENT.user.rememberMe) {
				g.drawImage(
						images.getPermaImage(8),
						((this.getWidth() - images.getPermaImage(8).getWidth(
								null)) / 2) + 140,
						((this.getHeight() - images.getPermaImage(8).getHeight(
								null)) / 2) - 110, null);
			}
		}

And here's the ImageCache:

package graphics;

import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.imageio.ImageIO;

public final class ImageCache {

	public ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
	public ArrayList<Integer> ids = new ArrayList<Integer>();
	public ArrayList<BufferedImage> permanentImages = new ArrayList<BufferedImage>();
	public ArrayList<Integer> pids = new ArrayList<Integer>();

	public void loadImage(String path, int id) {
		try {
			images.add(ImageIO.read(new File(path)));
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		ids.add(id);
	}

	public void writeCache() {
		String path = "./cache/sprites/gameframe/";
		File f = new File(path);
		byte[] b;
		String zipFile = "./Cache.dat";
		FileOutputStream fout = null;
		try {
			fout = new FileOutputStream(zipFile);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		ZipOutputStream zout = new ZipOutputStream(new BufferedOutputStream(
				fout));

		File[] s = f.listFiles();
		for (int i = 0; i < s.length; i++) {
			b = new byte[2028];
			FileInputStream fin = null;
			try {
				fin = new FileInputStream(s[i]);
				zout.putNextEntry(new ZipEntry(s[i].getName()));
				int length;
				while ((length = fin.read(b, 0, 1024)) > 0) {
					zout.write(b, 0, length);
				}
				zout.closeEntry();
				fin.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			zout.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void clearCache() {
		images.clear();
		ids.clear();
	}

	public void loadPermanentImage(String path, int id) {
		try {
			permanentImages.add(ImageIO.read(new File(path)));
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		pids.add(id);
	}

	public BufferedImage getImage(int id) {
		for (int i = 0; i < ids.size(); i++) {
			if (ids.get(i) == id) {
				return images.get(i);
			}
		}
		return null;
	}

	public BufferedImage getPermaImage(int id) {
		for (int i = 0; i < pids.size(); i++) {
			if (pids.get(i) == id) {
				return permanentImages.get(i);
			}
		}
		return null;
	}
}


Edited by Chall, 11 May 2014 - 08:13 PM.

Speaks fluent Java

#2 gonerogue

gonerogue

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 197 posts

Posted 11 May 2014 - 10:31 PM

In getImage() and getPermaImage(), is probably not enough to just return the cached image at the specified ID. You also need to set the element in the ArrayList to null at the index of your cached image element, in order to prevent loitering. See also: http://stackoverflow...bage-collection


Edited by gonerogue, 11 May 2014 - 11:06 PM.


#3 mailMindlin

mailMindlin

    CC Regular

  • Member
  • PipPipPip
  • 27 posts

Posted 12 May 2014 - 05:32 AM

You could try forcing garbage collection:

   public static void forceGC() {
     Object obj = new Object();
     WeakReference ref = new WeakReference<Object>(obj);
     obj = null;
     while(ref.get() != null) {
       System.gc();
     }
   }

Source



#4 wim DC

wim DC

    Roar

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 2681 posts

Posted 12 May 2014 - 06:50 AM   Best Answer

Issue was solved on SO.
Solution was to not initialize the Font variables on every paint call.

#5 Chall

Chall

    CC Addict

  • Senior Member
  • PipPipPipPipPip
  • 349 posts

Posted 12 May 2014 - 02:20 PM

Issue was solved on SO.
Solution was to not initialize the Font variables on every paint call.

Correct. You get a brownie point. :D


Speaks fluent Java




Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download