【问题标题】:Java - paintComponent memory leakJava - paintComponent 内存泄漏
【发布时间】:2016-12-26 15:32:42
【问题描述】:

我现在正在使用 Swing 处理 Java GUI 项目(一个小型​​ Dungeon Crawler),我的 paintComponent 方法中似乎存在内存泄漏,但我无法弄清楚是什么原因造成的:

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;
    }
}

tileMapTile 对象的二维数组,但它们不会改变,所以它们不是罪魁祸首,typeToImage 包含一个简单的switch-case,它连接来自@ 的值987654327@ 枚举到我们在构造函数中创建的BufferedImage 对象之一。

类中没有其他可能导致内存泄漏的东西,但也许你可以帮我找到源头。

【问题讨论】:

  • 怀疑这是泄漏的原因,但不要在传递给 paintComponent(...) 方法的 Graphics 对象上使用g.dispose()。只有在方法中创建 Graphics 对象时才使用 dispose(),例如使用 g.createGraphics()
  • 如果您不知道导致泄漏的原因,您怎么知道在这种方法中发生了泄漏?请发布您的完整代码。也许您每次调用 typeToImage 时都在加载新图像?
  • @ToddSewell 这是完整的代码,减去一些我注释掉的旧代码,以防我以后需要它。
  • 不,我的意思是完整的代码,我可以运行的东西。把全班贴在这里。我对 typeToImage 方法特别感兴趣。
  • 你也可以回复/考虑已经发布的 cmets 吗?

标签: java swing graphics jpanel paintcomponent


【解决方案1】:

我认为BufferedImage 会导致内存泄漏。我也有几乎类似的情况。在一个长时间运行的线程中,我正在绘制一个组件。每次调用该函数时,我都会创建一个新的BufferedImage,但在完成绘图后,BufferedImage 占用的内存不会被垃圾收集。只要应用程序正在运行,内存使用量就会增加。

从技术上讲,这不是内存泄漏。 GC 不会立即清除BufferedImage 占用的内存。它在必要时清除内存(取决于您的堆、堆栈、永久空间等分配)。可以通过调整-Xmx参数来测试(有没有OutOfMemoryError)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 2015-08-14
    • 2012-08-11
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多