I'm working in a Java GUI project right now (a small Dungeon Crawler) using Swing and there seems to be a memory leak in my paintComponent
method, but I can't make out what causes it:
class GamePanel extends JPanel {
private BufferedImage floor;
private BufferedImage wall;
private BufferedImage nullTile;
private TileMap tileMap;
private int centerImageX;
private int centerImageY;
public GamePanel(TileMap t) {
//setTitle("Dungeon Crawler v0.1a");
tileMap=t;
setSize(800,600);
centerImageY=(this.getHeight()/2)-16;
centerImageX=(this.getWidth()/2)-16;
setVisible(true);
try {
floor = ImageIO.read(new File(TileType.Floor.toString()+".png"));
wall = ImageIO.read(new File(TileType.Wall.toString()+".png"));
BufferedImage nullTileIn = ImageIO.read(new File(TileType.Null.toString()+".png"));
nullTile = new BufferedImage(nullTileIn.getWidth(),nullTileIn.getHeight(),BufferedImage.TYPE_INT_ARGB);
Graphics2D g = nullTile.createGraphics();
g.drawImage(nullTileIn,0,0,null);
g.dispose();
} catch (IOException e) {
System.out.println("Shit hit the fan");
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i=0;i<50;i++) {
for (int j=0;j<50;j++) {
g.drawImage(typeToImage(tileMap.getTile(i, j).type), i*32, j*32, null);
}
}
g.dispose();
}
private BufferedImage typeToImage(TileType t) {
switch (t) {
case Null:
return nullTile;
case Floor:
return floor;
case Wall:
return wall;
}
return nullTile;
}
}
tileMap
is a two-dimensional array of Tile
objects, but those don't change, so they're not the culprit, typeToImage
contains a simple switch-case
, that connects the values from the TileType
enum to one of the BufferedImage
objects that we're made in the constructor.
There is nothing else in the class that could cause a memory leak, but maybe you can help me find the source.
I think
BufferedImage
causes the memory leak. I also have almost the similar situation. In a long running thread, I am painting a component. I am creating a newBufferedImage
every time the function is called but after finishing the drawing the memory occupied by theBufferedImage
is not garbage collected. As long as the application is running memory usages increase.Technically, it is not the memory leak. GC does not clear the memory occupied by
BufferedImage
immediately. It clears memory when it is necessary (depending on your heap, stack, permspace, etc. allocation). You can test by tuning -Xmx parameter (whether there is anyOutOfMemoryError
).