Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 内存泄漏。不断上升直到游戏崩溃_Java_Android_Libgdx - Fatal编程技术网

Java 内存泄漏。不断上升直到游戏崩溃

Java 内存泄漏。不断上升直到游戏崩溃,java,android,libgdx,Java,Android,Libgdx,我是android开发的新手,我的游戏内存有问题。它不断上升直到崩溃。如果你能帮助我,我将不胜感激。多谢各位 另外,关于Spritebatch,我需要在java类中调用this.dispose吗?在java类中,我将其扩展到game,以便对其进行处理?如果是的话,我在哪里可以叫它?多谢各位 public class Zero implements Screen, InputProcessor { Pmacgame game; private Stage stage; pr

我是android开发的新手,我的游戏内存有问题。它不断上升直到崩溃。如果你能帮助我,我将不胜感激。多谢各位

另外,关于Spritebatch,我需要在java类中调用this.dispose吗?在java类中,我将其扩展到game,以便对其进行处理?如果是的话,我在哪里可以叫它?多谢各位

public class Zero implements Screen, InputProcessor {
    Pmacgame game;
    private Stage stage;
    private Skin skin;
    private Sound sound ,laser;
    private Music musicbg;
    private Sprite spritebg, playerImage;
    private ImageButton imgbtnLeft, imgbtnRight, fire, color1, color2, color3, color4,
                        bullet1, bullet2, bullet3, bullet4;
    public static final float fireDelay = 0.3f;
    String rr2;
    private static int o = 0;

    Rectangle player;
    ArrayList<Bullet> bullets;
    ArrayList<Target> targets;
    ArrayList<Explode> explodes;
    //long lastDrop;
    int score;
    boolean a, b;
    public static final float minSpawnTime = 0.5f;
    public static final float maxSpawnTime = 1.25f;
    float shootTimer, targetSpawnTimer;
    Random random;
    public static int select;
    public static int dis = 0;
    public float health = 1;
    private Sprite greenBar, redBar, blueBar, pinkBar, greenBarO, redBarO, blueBarO, pinkBarO;
    public Zero(Pmacgame game){



    @Override
    public void render(float delta) {

        shootTimer += Gdx.graphics.getDeltaTime();
        ArrayList<Bullet> bulletsToRemove = new ArrayList<>();

            if (fire.isPressed() && shootTimer >= fireDelay) {
                shootTimer = 0;
                bullets.add(new Bullet(player.x + 32f));
            }


            for (Bullet bullet : bullets) {
                bullet.update(Gdx.graphics.getDeltaTime());
                if (bullet.remove)
                    bulletsToRemove.add(bullet);
            }

        targetSpawnTimer -= Gdx.graphics.getDeltaTime();
        if (targetSpawnTimer<=0){
            targetSpawnTimer = random.nextFloat() * (maxSpawnTime -minSpawnTime) + minSpawnTime;
            targets.add(new Target(MathUtils.random(267, Gdx.graphics.getWidth()-350f)));
        }
        ArrayList<Target> targetsToRemove = new ArrayList<>();
        for (Target target: targets){
            target.update(delta);
            if (target.remove)
                targetsToRemove.add(target);
            if (target.getY()<=0){
                health -= 0.1f;
                if (health<=0){
                    select = 0;
                    dis = 1;
                    this.dispose();
                    game.setScreen(new GameOverScreen(game, score));
                    return;
                }
            }
        }


        ArrayList<Explode> explodesToRemove = new ArrayList<>();
        for (Explode explode: explodes){
            explode.update(delta);
            if (explode.remove)
                explodesToRemove.add(explode);
        }
        explodes.removeAll(explodesToRemove);

        for (Bullet bullet: bullets){
            for (Target target: targets){
                if (bullet.getCollisionRect().collidesWith(target.getCollisionRect())){

                    targetsToRemove.add(target);
                    bulletsToRemove.add(bullet);
                    score+=5;
                    explodes.add(new Explode(target.getX(), target.getY()));
                    sound.play(1f, 1.3f, 0f);
                }
            }
        }

        targets.removeAll(targetsToRemove);
        bullets.removeAll(bulletsToRemove);

        //Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        game.batch.begin();
        spritebg.draw(game.batch);
        game.batch.draw(blueBarO, 0, 575, blueBarO.getWidth(), blueBarO.getHeight());
        game.batch.draw(redBarO, 0, 550, redBarO.getWidth(), redBarO.getHeight());
        game.batch.draw(greenBarO, 0, 525, greenBarO.getWidth(), greenBarO.getHeight());
        game.batch.draw(pinkBarO, 0, 600, pinkBarO.getWidth(), pinkBarO.getHeight());
        game.font.draw(game.batch, "SCORE: " + score, 40, Gdx.graphics.getHeight() - 40 );
        for (Bullet bullet: bullets){
            bullet.render(game.batch);
        }
        for (Target target: targets){
            target.render(game.batch);
        }
        for (Explode explode: explodes){
            explode.render(game.batch);
        }
        if (health == 0) greenBar.setSize(greenBar.getWidth(), 0f);
        game.batch.draw(greenBar, 0, 525, greenBar.getWidth() * health, greenBar.getHeight());
        game.batch.draw(redBar, 0, 550, redBar.getWidth(), redBar.getHeight());
        game.batch.draw(blueBar, 0, 575, blueBar.getWidth(), blueBar.getHeight());
        game.batch.draw(pinkBar, 0, 600, pinkBar.getWidth(), pinkBar.getHeight());
        game.batch.draw(playerImage, player.x, player.y, player.width, player.height);
        game.batch.end();


        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();
        if (a) player.x -= 450 * Gdx.graphics.getDeltaTime();
        if (b) player.x += 450 * Gdx.graphics.getDeltaTime();
        if (player.x < 65f + imgbtnLeft.getWidth() + imgbtnRight.getWidth())
            player.x = 65f + imgbtnLeft.getWidth() + imgbtnRight.getWidth();
        if (player.x > Gdx.graphics.getWidth() - 350f)
            player.x = Gdx.graphics.getWidth() - 350f;
    }

    @Override
    public void dispose () {
        musicbg.dispose();
        laser.dispose();
        stage.dispose();
        skin.dispose();
        sound.dispose();

    }

}

我在字里行间阅读,但看起来您必须在Bullet/Target/Explosion的构造函数中加载纹理,因为我没有看到您将纹理或TextureRegion引用传递给它们的构造函数或
render
方法

你应该在一个类中加载所有纹理,并传递对游戏对象的引用,以便它们“借用”和绘制。否则,您会无缘无故地加载同一图像的多个副本

此外,纹理是一次性的,这意味着它使用本机内存,并且在让垃圾收集器接收它之前必须对其调用
dispose()
。否则,本机内存将泄漏

在您的情况下,所有这些子弹、目标和爆炸都会一遍又一遍地加载许多纹理,并且在删除它们时从不处理它们

关于你关于SpriteBatch的问题。是的,您应该在实例化它的同一个类中处理它,并且
dispose()
是正确的处理位置

编辑,裸体示例:

public class Assets implements Disposable {

    public final Texture horse;
    public final Texture bullet;
    // etc.

    public Assets (){
        horse = new Texture("horse.png");
        //...
    }

    public void dispose(){
        horse.dispose();
        //...
    }
}

public class Zero implements Screen, InputProcessor {
    private final Assets assets;
    //...

    public Zero (){
        assets = new Assets();
        //...
    }

    //...

    public void dispose(){
        assets.dispose();
        //...
    }
}

public class Bullet {
    //...

    public void render(SpriteBatch batch, Assets assets){
         batch.render(assets.bullet, /*...*/);
    }
}

子弹、目标、爆炸类的数据成员是什么。检查是否值得在render方法中创建这些类的对象。如果频繁创建对象,请尝试使用池API。在渲染方法内创建容器(Arraylist)??注释掉新语句,并检查内存泄漏是否仍然发生。逐一进行联合国评论,找出问题所在。当然,正如Aryan所说,不要在render方法(每帧)中分配它们,而是在create方法中分配它们。你是对的,我在它们的构造函数中加载纹理。如果你能给我一个例子,让我用一个类来处理我的纹理,然后通过引用传递它们,我将不胜感激。谢谢。@ZerOjMac我添加了一个示例。但您还应该研究LibGDX的AssetManager类,因为它是处理资产的更好方法,而不是自己手动加载每个资产。在您了解如何使用它之后,我建议您查找CoveTools库,并使用其AssignmentAssetManager删除大量样板代码。非常感谢您提供的信息,我将查看您提到的内容。@ZerOjMac不客气。另外,我注意到另一件不相关的事情。。。在渲染循环中创建许多新的ArrayList。这可能会导致帧速率出现小的停顿,因为它必须分配ArrayList的备份数组,可能必须在填充时调整其大小(这意味着分配一个更大的数组并复制第一个数组),然后必须取消分配备份数组。我建议对这些列表使用最终成员字段,以便只分配一次。这可能有点晚了,但多亏了你,我成功开发了我的第一个游戏。它仍然没有完成,因为我仍然有想法,但看看它。
public class Assets implements Disposable {

    public final Texture horse;
    public final Texture bullet;
    // etc.

    public Assets (){
        horse = new Texture("horse.png");
        //...
    }

    public void dispose(){
        horse.dispose();
        //...
    }
}

public class Zero implements Screen, InputProcessor {
    private final Assets assets;
    //...

    public Zero (){
        assets = new Assets();
        //...
    }

    //...

    public void dispose(){
        assets.dispose();
        //...
    }
}

public class Bullet {
    //...

    public void render(SpriteBatch batch, Assets assets){
         batch.render(assets.bullet, /*...*/);
    }
}