-1

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.

Frakcool
  • 10,915
  • 9
  • 50
  • 89
Masterhaend
  • 44
  • 1
  • 6
  • Doubt it is the cause of the leak but don't use `g.dispose()` on the Graphics object passed to the paintComponent(...) method. Only use dispose() if you create a Graphics object in the method, for example by use `g.createGraphics()`. – camickr Dec 26 '16 at 15:37
  • If you don't know what causes the leak, how do you know it happens in this method? Please post your full code. Maybe you're loading a new image each time typeToImage is called? – Todd Sewell Dec 26 '16 at 15:39
  • @ToddSewell this is the full code, minus a bit of old code that I commented out incase I need it later. – Masterhaend Dec 26 '16 at 15:53
  • No I meant the full code, something that I could run. Just post the whole class here. I'm particularly interested in the typeToImage method. – Todd Sewell Dec 26 '16 at 16:34
  • And could you also reply to/take into account the comments that were already posted? – Todd Sewell Dec 26 '16 at 16:45
  • It doesn't look like there is a memory leak in this code to me, but I can't test until later today. Why do you think there is one? – Todd Sewell Dec 26 '16 at 20:45
  • @ToddSewell memory keeps increasing every time paintComponent is called e.g. while moving the window around, I did find out (a few hours after asking this question) that the increases drastically slow down nearing a certain value. – Masterhaend Dec 26 '16 at 23:05
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). 3) A single blank line of white space in source code is all that is *ever* needed. Blank lines after `{` or before `}` are also typically redundant. 4) **I doubt there is really a memory leak. The JRE will only call the garbage collector if it feels it *necessary* to do so. Watching 'memory size' is premature optimisation.** – Andrew Thompson Dec 26 '16 at 23:39

1 Answers1

0

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 new BufferedImage every time the function is called but after finishing the drawing the memory occupied by the BufferedImage 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 any OutOfMemoryError).

Mokarrom Hossain
  • 357
  • 1
  • 11