Java 垃圾收集问题

Java 垃圾收集问题,java,c++,actionscript-3,garbage-collection,Java,C++,Actionscript 3,Garbage Collection,考虑以下代码段: function loadSomeContent() { URLLoader loader = new URLLoader("http://www.somesite.com/"); loader.addEventListner("onLoadComplete", loadCompleteHandler); loader.sendHttpRequest(); } function loadCompleteHandler(event) { lo

考虑以下代码段:

function loadSomeContent()
{
    URLLoader loader = new URLLoader("http://www.somesite.com/");

    loader.addEventListner("onLoadComplete", loadCompleteHandler);

    loader.sendHttpRequest();
}

function loadCompleteHandler(event)
{
    log("Load response received");
}
不要担心这段代码的语法


这里是我关心的问题-用于发送HTTP请求且已注册onLoadComplete事件的loader对象不是从loadSomeContent()函数外部引用的。是否有可能会对loader对象进行垃圾收集,并且永远不会调用loadCompleteHandler()?

当您调用
loader.sendHttpRequest()
时,将创建一个新线程,该线程将实际在后台发送请求。此线程保留对加载程序的引用,以便在加载完成时调用load complete函数。因此,加载程序将始终由某个线程引用,而不是您当前所在的线程。

否。只要URLLoader包含仍在某个位置引用的回调,就不会引用(在本例中,它仍然被Javascript引擎/JVM/任何东西引用,因为引擎以后必须调用它。

根据我的经验,活动的加载程序对象(如
URLLoader
loader
)不会被收集(当它处于活动状态时)

然而,一个不应该被忽略的重要点是,这充其量是一个可观察的行为,但并没有这样的记录(至少,据我所知,我可能错了)

因此,尽管播放器使用内部机制来实现这一点(无论它是否创建新线程、使用集中式和全局连接池等),我认为您不应该依赖于此,因为您将代码绑定到实现细节(同样,如果记录了此行为,则不适用!)

另外,正如我在一篇评论中提到的,
flash.net
API中有一个类,
FileReference
,如果您在代码中使用该类,则可以收集该类

因此,总而言之:您可能不需要根据当前的工作方式(以及观察!)存储本地引用,但这并不能保证,因此您最好在加载程序处于活动状态时存储非本地引用。

只有在以下情况下:

function loadCompleteHandler(e: event): void{
    (e.target as URLLoader).removeEventListner("onLoadComplete", loadCompleteHandler);
}

它应该由AS3 GC收集(这样就没有引用了,所以我们无法检查这个本地变量是否存在:)

在actionscript中,加载程序不会被垃圾收集。事件处理程序仍然注册为链接,因为您没有向其添加弱引用。实际上,我经常这样做是为了加载,我喜欢这样做,因为您不必存储对象数组来处理引用

如果添加弱引用,则会中断:

loader.addEventListner("onLoadComplete", loadCompleteHandler, false, 0, true);
如果不清除loadCompleteHandler中的引用,可能会出现内存问题

function loadCompleteHandler(event) {
    (event.currentTarget as URLLoader).removeEventListener('onLoadComplete');
}

那么,这是特定于语言的,还是支持异步事件的每种语言都会通过创建一个新线程来实现这一点呢?实际上不一定要创建一个新线程,但无论采用何种机制来实现延迟执行,都需要有某种方式来保存对它应该执行的事情的引用!它将如何执行以后会怎么样?根据经验,我倾向于同意你的观点,即加载程序在实践中处于活动状态时不会被收集。但这种行为在任何规范中都没有记录(至少据我所知)因此,我要说的是,不要依赖于此。NetAPI中还有另一个对象,即
FileReference
,如果您不将其锁定(即使您已经开始下载),它肯定是可以收集的我认为这是API中的一个bug。如果一个对象选择延迟它的动作,而不是那个对象应该负责维护它的生命周期,或者这个事实应该在API中被清楚地记录。为什么用C++、java和oop-标签来删除OOP?添加垃圾收集。我不知道它们是否属于。OOP、C++和java的原因是因为我想把问题泛化到这些OOP语言,而不限于AS3。这也是我要求读者不必担心语法的原因。我认为你不能对此有一个通用的答案。这似乎是依赖于实现的。MO.恐怕这反映了对回调函数和侦听器的一种常见误解。添加侦听器本身并不会阻止dispatcher被收集。回调函数/闭包不是这里的重点。根据观察,加载程序处于活动状态这一事实会阻止它被收集,但据我所知,这并没有记录在案行为,因此它可能会在将来的版本中更改。我认为您最好在加载程序使用时存储对加载程序的非本地引用。@Juan:不,这是错误的。线程堆栈中的内容或至少可以从堆栈中的一个项访问的内容不会被收集。请看一个java程序-所有正在运行的内容都是“刚刚”的线程。我不同意。从actionscript的角度来看,加载程序是不可访问的。当然,它是活动的,玩家可以访问,但这是一个内部实现细节。对于加载程序,当它处于活动状态时,它不会被收集。这是一种特殊情况(运行计时器是另一种情况)和“抽象泄漏”,可以这么说。但是回调并没有阻止加载程序被收集。不要相信我的话,自己试试。将所有需要的回调添加到加载程序中。同时,有一个函数可以在给定的时间间隔调用System.gc。(续)您将看到,无论是否删除回调,加载程序最终都会被收集。如果您启动了加载操作,则在该操作完成(或失败)后,它将被收集。同样,这是因为加载程序处于活动状态,而不是因为您向其添加了侦听器。另一方面,如果您不调用load(),加载程序可以立即收集(尽管有事件侦听器)@www0z0k。抱歉,这是错误的。加载程序引用了处理程序(并间接引用了定义处理程序的对象)。这意味着可以从