【问题标题】:Java Graphics Dispose MethodJava 图形处理方法
【发布时间】:2015-08-22 04:16:47
【问题描述】:

我想知道一段代码:

public void render()
{
    BufferStrategy bs = getBufferStrategy();

    if(bs == null)
    {
        createBufferStrategy(3);
        return;
    }

    Graphics g = bs.getDrawGraphics();

    g.dispose();
    bs.show();
}

渲染在游戏循环中。

在我正在阅读的书中,它说我需要在这里调用 dispose。我真的不明白为什么。不是每次渲染循环都会覆盖 g 吗?

【问题讨论】:

    标签: java graphics 2d-games


    【解决方案1】:

    根据JavaDoc 应该是出于性能原因。如果所有引用都被释放,它将通过垃圾收集器自行处理。

    你在问:

    不是每次渲染循环都会覆盖 g 吗?

    好吧,在您的情况下,您每次查询图形上下文时都会创建一个 new Graphics 对象。因此,应该像只调用一次那样调用 dispose,因为每个实例都是一个孤立的案例。

    【讨论】:

    • 嗯,我明白我们为什么使用 dispose(),但让我困惑的是为什么我们需要在每次循环迭代后进行 dispose。由于 g 处的数据在每次迭代后都会被覆盖,一旦循环结束,在最后处理不是更有效吗?
    • 我提到渲染是在一个游戏循环中。基本上循环直到满足某个条件。即角色死亡。
    • 等等,你能告诉我这是否正确吗?每次都会创建一个新的图形上下文,所以即使 g 不再引用旧的上下文,旧的数据也可能不会立即被收集,所以最好马上摆脱它。 – user2776326 2 分钟前
    【解决方案2】:

    每个Graphics 对象都使用系统资源,这些资源应该被释放。这与需要在您打开的InputStream 上调用close() 大致相同。

    如果不这样做,对象的finalize() 方法中有代码将返回资源。但是 Java 中的一个已知问题是 finalize() 可能被调用得很晚,或者根本不调用,因此这些资源永远不会被清除。这可能会导致程序在资源耗尽时停止工作。

    你可能会想,因为在render() 的末尾,变量g 超出了范围,无论如何它都会被垃圾回收。但它只是成为收藏的候选者。具有终结器的对象不会很快收集 - 终结器必须在对象被完全删除之前运行。在任何情况下,垃圾收集都会处理内存分配,而不是其他系统资源。

    documentation of the dispose() method itself 对此进行了简要说明。


    请注意,the documentation for BufferStrategy.getDrawGraphics() 告诉您,每次调用它时,它都会创建一个图形上下文。也就是说,您每次都不会得到相同的对象 - 它是每次调用 getDrawGraphics() 的新对象。

    【讨论】:

    • 嗯,我明白我们为什么使用 dispose(),但让我困惑的是为什么我们需要在每次循环迭代后进行 dispose。由于 g 处的数据无论如何都会在每次迭代后被覆盖,一旦循环结束,在最后处理不是更有效吗?
    • @user2776326 我补充了一点。
    • 等等,你能告诉我这是否正确吗?每次都会创建一个新的图形上下文,所以即使 g 不再引用旧的上下文,旧的数据也可能不会立即被收集,所以最好马上摆脱它。
    • 或多或少,但问题不在于它可能不会立即收集,而是它使用系统资源的事实,应该总是清理谁分配它们,不像堆内存。您不应该信任 finalize() 方法,因为它可能永远不会被调用。
    • 好吧,我想我有点假设通过使 g 不再指向对象它会消失,但实际上该对象仍然存在于内存中的某个位置,直到调用 finalize。
    猜你喜欢
    • 1970-01-01
    • 2012-05-14
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    相关资源
    最近更新 更多