2016-12-26 5 views
-1

Я работаю над проектом Java GUI прямо сейчас (маленький Dungeon Crawler) с использованием Swing и, похоже, происходит утечка памяти в моем методе paintComponent, но я не могу разобраться, что вызывает его :Java - paintComponent memory leak

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 является двумерный массив Tile объектов, но те не меняются, поэтому они не преступник, typeToImage содержит простой switch-case, который соединяет значения из TileType перечисления в один объектов BufferedImage, которые мы создали в конструкторе.

В этом классе нет ничего, что могло бы вызвать утечку памяти, но, возможно, вы можете помочь мне найти источник.

+0

Сомнение вызывает утечку, но не использует 'g.dispose()' объекта Graphics, переданного методу paintComponent (...). Используйте метод dispose(), если вы создаете объект Graphics в методе, например, используя 'g.createGraphics()'. – camickr

+0

Если вы не знаете, что вызывает утечку, откуда вы знаете, что это происходит в этом методе? Пожалуйста, разместите свой полный код. Может быть, вы загружаете новое изображение каждый раз, когда вызывается типToImage? –

+0

@ToddSewell это полный код, минус немного старого кода, который я прокомментировал, потому что мне это нужно позже. – Masterhaend

ответ

0

Я думаю, BufferedImage вызывает утечку памяти. У меня тоже почти такая же ситуация. В длинной нитке я рисую компонент. Я создаю новый BufferedImage каждый раз, когда вызывается функция, но после завершения чертежа память, занятая BufferedImage, не является сборкой мусора. Пока приложение запускает использование памяти, увеличивается.

Технически это не утечка памяти. GC не очищает память, занятую BufferedImage немедленно. Он очищает память, когда это необходимо (в зависимости от вашей кучи, стека, permspace и т. Д.). Вы можете проверить, настроив -Xmx параметр (есть ли OutOfMemoryError).