【问题标题】:Rendering textures causing memory leak渲染纹理导致内存泄漏
【发布时间】:2014-10-08 20:37:23
【问题描述】:

在我的游戏中,我有这个代码。它渲染一个用作按钮的纹理:

private void drawStart(){

    startTexture = new Texture(Gdx.files.internal("start.png"));
    startTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    stageStart = new Stage();
    stageStart.clear();
    buttonStart = new Image(startTexture);
    buttonStart.setX(10);
    buttonStart.setY(Gdx.graphics.getHeight()/2.75f);
    buttonStart.setWidth(Gdx.graphics.getWidth()/4);
    buttonStart.setHeight(Gdx.graphics.getHeight()/4);




    Gdx.input.setInputProcessor(stageStart);

    buttonStart.addListener(new ClickListener() {
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
        {
           currentState = GameState.RESET;
           startTexture.dispose();
           stageStart.dispose();


            return true;
        }
    });
    stageStart.addActor(buttonStart);
    stageStart.draw();
    startTexture.dispose();

}

然而,每当我把 drawStart();在我的渲染方法中,Java Heap 和 Native Heap 每 10 秒缓慢增加 1。因此,如果用户在菜单上离开游戏大约 5 分钟,游戏就会在他们的手机上崩溃。我已经测试过了,它只在纹理渲染时发生。

如果能帮助我解决这个问题,我将不胜感激。我尝试了一个 if 语句,声明如果渲染 = 0,渲染纹理然后设置渲染 1,但这不起作用。

【问题讨论】:

  • 为什么要将drawStart() 放入渲染方法中?这基本上是在每秒大约 60 次创建一个新纹理、新舞台(没有正确处理它)、新图像和一个新 ClickListener?
  • 抱歉我的代码不好,我三个月前才学java。我将如何只渲染一次?
  • Libgdx 并不是学习 java 的最佳起点。如果您的意思是您认为您知道(并且理解)足够的 java 以进入 libgdx,那么我建议您查看the tutorials 之一,以便您确定了解lifecycle .但是,正如前面所说,强烈建议您至少了解 java、oop(尤其是 gc)的基本知识。

标签: java memory memory-management memory-leaks libgdx


【解决方案1】:

这可能会对您有所帮助。您只需要在渲染中绘制。所以现在你可以把 drawStart() 放在你的渲染方法中,它只会绘制舞台,而离开屏幕时不要忘记调用 dispose。

    private void drawStart(){
        stageStart.draw();
    }

    public void initialize() {
        startTexture = new Texture(Gdx.files.internal("start.png"));
        startTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        stageStart = new Stage();
        stageStart.clear();
        buttonStart = new Image(startTexture);
        buttonStart.setX(10);
        buttonStart.setY(Gdx.graphics.getHeight()/2.75f);
        buttonStart.setWidth(Gdx.graphics.getWidth()/4);
        buttonStart.setHeight(Gdx.graphics.getHeight()/4);

        Gdx.input.setInputProcessor(stageStart);

        buttonStart.addListener(new ClickListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
            {
               currentState = GameState.RESET;
               startTexture.dispose();
               stageStart.dispose();


                return true;
            }
        });
        stageStart.addActor(buttonStart);
    }

    public void dispose() {
         startTexture.dispose();
    }

【讨论】:

  • 谢谢,Java Heap 和 Native Heap 现在只用了 1MB。
【解决方案2】:

您的问题是,在 drawStart() 中,您正在创建新的 Textures 和新的 Stage
如果您在每个渲染循环中调用它,您会以大约 60 次/秒的速度创建新的 Textures 和 new Stage
此 ofc 会导致内存泄漏。 您应该只在构造函数或create()show() 方法中加载/创建Textures 和Stage
还要考虑在需要时处理它们。 Here 是您需要手动处理的东西的列表。
在渲染循环中,您应该只更新和绘制事物。

但由于您只有 3 个月的经验,我建议您先学习基础知识。不要急于进行游戏编程,这会扼杀你的动力。
首先学习基础知识,然后从一些 ASCII-Games(命令行)开始,然后您可以从 libgdx 开始。

如果您准备好使用 libgdx,请阅读 Wiki(至少是您需要的部分)以及一些 tutorials(可能他们不使用最新版本的 libgdx,但概念应该更多或不太一样,它应该可以帮助您理解它。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-30
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2014-06-07
    • 2013-11-20
    • 2011-10-28
    相关资源
    最近更新 更多