Java垃圾收集和图形处理的dispose方法

4
我正在制作一个游戏(贪吃蛇的克隆版),这是我的业余爱好。我正在查看 Java API 中 Graphics 类的 dispose 方法。当我注释掉 dispose 方法时,我的动画能够正常工作,没有任何问题。在 Java API 中,dispose 方法的作用是释放图形上下文正在使用的系统资源。Java 垃圾回收不是在管理程序的内存方面与 dispose 的作用相似吗?我应该保留 dispose 方法吗?
API 对于 sync 方法的解释帮助不大。但是从其他论坛上的阅读中,ToolKit 类中的 sync 方法是为了确保绘制操作(比如 paintComponent 方法)刷新到图形卡上。因此,图形卡的工作是清除程序之前的任何图形上下文的遗留物吗?
以下是代码:
 public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Toolkit.getDefaultToolkit().sync();
            g.dispose();

     }

5
Javadoc指出:当Java程序运行时,短时间内可能会创建大量的Graphics对象。虽然垃圾回收的最终化过程也会处理相同的系统资源,但最好通过调用此方法手动释放相关资源,而不是依赖可能长时间才能完成的最终化过程。 - Greg Kopff
1
永远不要依赖垃圾回收器来处理系统/非托管资源。你的GC可能需要几分钟才能启动,而你的图形堆栈可能已经用尽,结果是你将停止看到图形,即使有大量的空闲内存。这在Java中发生,在.NET中并不重要,因为GUI对象池是受限制的,即使你有8GB的内存,也不能指望分配1,000,000个画笔。你拥有的内存越多,GC就越不积极,这就是问题所在。我见过太多在.NET中的应用程序绘制“红十字”而不是按钮和图像,然后在5分钟内恢复正常。 - itadapter DKh
1
图形堆栈位于操作系统中 - 它是一个逻辑部分,在Windows上例如在gdi.dll中。如果设备驱动程序支持某些硬件加速,那么诸如笔刷和钢笔之类的东西就可以进入PCI卡中。但GDI是具有内部固定大小数组的瓶颈。例如,在Android上,2D绘图是使用SKIA库进行的,而每个笔刷/钢笔需要大量的RAM。 - itadapter DKh
1
@Nicholas:http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#dispose%28%29 - Greg Kopff
1
图形堆栈 = 就像“图形组件”一样,它们是渲染2D基元(至少)和窗口管理功能(管理位图在区域中显示的功能)的机制。这就是我所说的图形堆栈。不要与用于执行代码的堆栈段混淆,这是一个CPU专门用途的寄存器(用于相对寻址和引用临时值的指针寄存器)。 - itadapter DKh
显示剩余5条评论
1个回答

8

说到图形处理,有一个简单的原则。

如果你明确地创建了它(例如BuffereImage.createGraphics()),那么就要销毁它。

另一方面,在paintComponent(Graphics g)中,实例g是由工具包提供的,并且在需要时/如果需要时进行销毁。在您自己的代码中这样做会导致“不可预测”的渲染。


1
我从Java文档中阅读到以下内容:为了提高效率,程序员应该仅在Graphics对象是直接从组件或另一个Graphics对象创建而来时才在使用完毕后调用dispose方法。由于Graphics对象是创建图形上下文g的对象,所以我应该自己将其dispose掉。我会谨记这个原则。非常感谢您的知识分享,Andrew! - Nicholas
同样的答案在这里讨论:http://www.coderanch.com/t/540134/Performance/java/Graphics-dispose。 - Benj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接