匿名类是否保持外部引用活动?

时间:2011-10-31 04:07:31

标签: java android multithreading

浏览以下链接:GLSurfaceView code sample

具体来说,请查看该页面第二个代码块中的以下函数:

public boolean onTouchEvent(final MotionEvent event) {
    queueEvent(new Runnable() {
        public void run() {
            mRenderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f);
        }
     });

     return true;
}

让我感到困惑的是,anon Runnable引用了非常本地的“event”对象,但是queueEvent实际上最终在一个完全独立的线程上运行Runnable,因此很可能在“event”的特定实例很长之后很久死了,这显然是一个问题。或者情况是,在“事件”对象的引用计数上,某种local-ref-in-anon-class用法实际上是+1,这样只要anon Runnable仍在呼吸,它就会一直存在?< / p>

此外,MotionEven被宣布为final的事实是否与所有这些有关?

P.S。 作为一个相关的问题(虽然这不是我主要考虑的问题),如果不是(或者除了)“event”之外我们想要在anon类中引用一些类似“int x”的原语,那么会发生什么呢? (因为你不能+1原语的引用计数)。

3 个答案:

答案 0 :(得分:4)

是的,Runnable会保留对MotionEvent的引用。在MotionEvent可收集之前,Runnable无法进行垃圾回收。

只能在内部类中引用final个局部变量。

顺便说一句,不要假设使用引用计数;现在大多数垃圾收集者都不使用引用计数。

答案 1 :(得分:3)

Java不使用引用计数来进行垃圾回收。我不太清楚JVM如何实现这种闭包,但我只能假定匿名类实例包含对event的引用。既然如此,只要匿名的Runnable是活着的,那么它引用的所有东西都是活着的(这些东西所引用的东西都是活着的等等)。

对于原始类型,它们只是直接复制到字段中。因此,只要它被引用然后被垃圾收集,就没有“引用”需要生存的东西;它们只是包含它们的对象的一部分。每次你对int 287“做一个新的引用”时,并不是存在一个存储287的地方你现在有另一个引用,你只有另一个存储单词存储287.所以无论何时287你都没关系最初是你的,取消分配,你的是完全独立的。

答案 2 :(得分:2)

如果变量被声明为final,则只能引用该变量,并且线程将保留对它的引用,从而阻止它被垃圾回收。

相关问题