Java 2D游戏内存泄漏

时间:2019-01-21 21:41:46

标签: java

这是我第一次使用stackoverflow并希望获得一些帮助以了解我遇到的问题。在时间允许的范围内,我已经从事几个月的2D切片游戏的工作了几个月,但是我认为在绘制图形或至少在代码的那部分地方遇到了内存泄漏。一切正常,游戏运行,所有图像渲染,等等,但是昨晚我决定看看运行该程序时cpu和内存是如何保持的。我注意到随着时间的流逝,内存只会不断增长。从大约50mb开始,超过10-15分钟可以增长到150mb。我注释掉了一段代码,其中绘制了图形,并且执行了计时器的操作。我认为罪魁祸首在那附近,因为我认为注释时内存没有不必要的增长。

在绘制图形的类中,我创建并存储一个大约864x768的缓冲图像,并使用各种32x32的较小图像组成。

我使用一个经常触发的javax.swing.Timer,在执行动作的方法中,我只运行了update()方法,该方法检查玩家的输入,然后通过缓冲图像获取大缓冲图像的子图像。 subimage方法并将其显示在画布上。

我想这可能与计时器有关,但不确定。

下面是一些代码:

    private BufferedImage map;
    private Timer timer;            
    private BufferStrategy bs;
    private Graphics g;
    private boolean isInitialized; 

    public class World extends Canvas implements ActionListener {

        public World() {
            isInitialized = false;
            timer = new Timer(25, this);
            timer.setInitialDelay(100);
            timer.start();
        }   

        @Override
        public void actionPerformed(ActionEvent e) {
            if(!isInitialized) {
                createBufferStrategy(3);
                bs = getBufferStrategy();
                isInitialied = true;
            }
            update();
        }

        public void update() {
            player.input();
            g = bs.getDrawGraphics();
            BufferedImage temp = map.getSubimage(x, 
                y, viewWidth, viewHeight);
            g.drawImage(temp, 0, 0, null);
            g.drawImage(player, playerX, playerY,
                null);
            bs.show();
            g.dispose();
        }

    }

提前谢谢!!

编辑:

好的,所以花了一些时间研究垃圾回收,JVM等之后,我发现我不了解这些东西在基本水平上是如何工作的。我对该项目进行了概要分析,发现GC可以按预期工作,依此类推。因此,总的来说,我认为是内存泄漏的情况不一定如此。我最初担心的是,从Windows任务管理器中我看到内存正在增长,并且从未稳定过该过程,而我只是知道该过程从代码,第二次检查,尝试不同的代码等是不正确的。我感到了解我现在所知道的要多得多!

我也采用了这种方法:

public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2,
    int dy2, int sx1, int sy1, int sx2, ImageObserver observer)

代替:     BufferedImage temp = map.getSubimage(x,y,viewWidth,viewHeight);     g.drawImage(temp,0,0,null);

现在我遇到了另一个问题。在我的台式机上,我用于编程和测试游戏,一切运行正常,并且可以在不使用任何应用程序的情况下测试游戏时正常运行。但是,当我启动浏览器并尝试在youtube或netflix上观看某些内容然后测试运行游戏时,会出现一毫秒的暂停(从25到50毫秒不等)。这种暂停每秒发生一次,这是明显的,绝对是不希望的!我进行了一些测试,它仅在以下draw方法期间发生:

公共抽象布尔drawImage(Image img,int dx1,int dy1,int dx2,         dy2,int sx1,int sy1,int sx2,ImageObserver观察器)

但是同样,仅在特定情况下,即使在该情况下,每次也要在1-2毫秒内完成,除非经过一秒钟或接近它,否则会有延迟。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我看不到要刷新BufferedImage的任何地方,因此它将保留先前分配的所有内存。

完成BufferedImage temp值后,需要使用temp.flush()刷新它

答案 1 :(得分:0)

无需获取子图像即可将其绘制到Graphics中。

public abstract boolean drawImage(Image img,
                int dx1,
                int dy1,
                int dx2,
                int dy2,
                int sx1,
                int sy1,
                int sx2,
                int sy2,
                ImageObserver observer)

This overload of drawImage允许您指定要直接绘制的源图像部分:s中的sx1sy1等参数表示“源”。