Actionscript 3 为什么没有事件侦听器或引用的封闭网络连接会留在内存中?

Actionscript 3 为什么没有事件侦听器或引用的封闭网络连接会留在内存中?,actionscript-3,flash,memory-management,memory-leaks,amfphp,Actionscript 3,Flash,Memory Management,Memory Leaks,Amfphp,如果flash.net.NetConnection被实例化并连接到HTTP URL(如AMFPHP网关),则该实例即使在被关闭且唯一引用被设置为null之后,也不会被垃圾收集拾取 另一方面,如果实例连接到null(当用于播放视频/mp3文件时会这样做),则实例将从内存中清除 为了澄清,以下连接将保留在内存中: var stickyConn:NetConnection = new NetConnection(); stickyConn.connect("http://myserver/amfphp

如果flash.net.NetConnection被实例化并连接到HTTP URL(如AMFPHP网关),则该实例即使在被关闭且唯一引用被设置为null之后,也不会被垃圾收集拾取

另一方面,如果实例连接到null(当用于播放视频/mp3文件时会这样做),则实例将从内存中清除

为了澄清,以下连接将保留在内存中:

var stickyConn:NetConnection = new NetConnection();
stickyConn.connect("http://myserver/amfphp/gateway.php");
stickyConn.close();
stickyConn = null;
鉴于,以下连接将立即从内存中清除:

var tempConn:NetConnection = new NetConnection();
tempConn.connect(null);
tempConn.close();
tempConn = null;
我已经尝试解决了一些问题:

  • 将客户端设置为空对象(因为客户端的默认值是NetConnection本身)
  • 关闭连接之前,请调用
    connect(null)
  • 关闭连接后,调用
    connect(null)
    并再次关闭它

以前有人遇到过这个问题吗?有解决方法吗?

您是否使用NetStream对象,但在完成后不处理它?我之所以问这个问题,是因为我很少看到一个NetConnection后面没有NetStream对象。

我经常使用AS3构建重型FLV/Mp4播放器。当我使用Akamai或Adobe的内部NetConnection类等服务时,我始终牢记
客户端

是调用所有回调方法的NetConnection的属性。默认值是此NetConnection实例
this
。如果将客户机属性设置为另一个对象,则将在该对象上调用回调方法

通过这种方式,您可以很容易地理解垃圾收集从未以相同的方式在每个组件上真正应用。因此,其中
stickyConn=null只停止播放,因为您从未声明弱引用,垃圾收集不知道要查找什么

我已经成功地使用了基于特定玩家的不同方法:

简单地说明
NetConnectionObj.client=这通常就足够了。但是,如果您的网络连接被扩展或实现了接口,该怎么办?只需使用
null
字典对象: var d:Dictionary=newdictionary(true)。从这里,垃圾收集将识别“d”为弱引用并自动转储它

因此,您的代码片段看起来有点像这样:

var Dc:Dictionary=新字典(true)
NetConnection:NetConnection.client=Dc

或者有相同意图的一些变化


我知道这是可行的,所以如果您需要帮助,请联系我。

关于GC和Dictionary对象,我可能对最后一个答案不太清楚。请考虑一下这个片段。我写得很快,但我试图解释什么能解决你的问题;主要是因为我以前处理过:

public class Main extends MovieClip {

    private var connection:NetConnection;
    private var __nData:*;
    private var _instance:*;
    private var _closure:Function;
    private var _D:Dictionary;

    public function Main() {    
        connection = new NetConnection();
        connection.addEventListener(NetStatusEvent.NET_STATUS, _nsHandle)
        connection.connect(null);
    }
    public function _nsHandle(event:NetStatusEvent):void {
        try {
            connection = new NetConnection();
            connection.connect(null);
            connection.client = RegisterForGC(event.target);
            RegisterForGC(connection);
        } finally {
            __nData = event.target.netConnection;
        }           
    }
    public function RegisterForGC(NCObject:*):* {
        _instance = NCObject;
        _closure  = function  ():void       {}
        _listener = function (e:Event):void {}
        _D = new Dictionary(true);
        _D[_listener] = "A";
        _D[_instance] = "B";
        _D[_closure]  = "C";
        try {
            new LocalConnection().connect( "A" );
            new LocalConnection().connect( "B" );
        } catch (anything:*) { }
        return _instance;
    }
}

我不确定,但您的示例似乎表明您正在舞台/框架上声明您的VAR

close();不过,这一切都是你需要的。。。。 根据我对NetConnection的发现,出于某种原因,除非所有变量/函数都在外部类中声明,例如public vars public function, 即使在使用close()后,它仍保留在内存中

通过一个音频流项目来解决这个问题。 但是,一旦我将所有编码移动到外部类,close();实际上关闭了连接

如果您的代码在舞台上的框架上或在MC中,我将创建一个类,并在所述外部类中声明变量和函数。由于某些愚蠢的原因,它可以工作


希望这能有所帮助。

您在Amfphp 2.1或更高版本上尝试过吗?我没有;我要试一试。这是你自己测试过的吗?我用最新版本的Amfphp(2.1.1)进行了测试,结果没有什么不同。我从来没有真正检查过,也没有给予过太多的关注。此外,这是一个客户端问题,因此不会因此导致服务器内存过载。但我发现它很有趣,修复它会很酷。我不关心服务器内存。这是一个AIR应用程序,我关心的是客户端内存。诚然,NetConnection的单个实例会消耗少量内存;它只是让我恼火,它在不应该的时候挂在那里。没有涉及到NetStream对象。NetStream与NetConnection一起用于流式视频/声音。在本例中,NetConnection用于连接到AMFPHP网关。虽然不是特定问题的解决方案,但我发现这个答案很有帮助。在对任何问题进行故障排除时,有一个“常见嫌疑犯”列表可以查看,这很好。这个问题涉及的事实是,客户端中没有剩余的引用或任何东西,甚至没有事件侦听器。NetConnetion已关闭,其引用已彻底删除,所有内容都已删除。我注意到的唯一一件事是,FMS似乎仍然非常坚决地认为客户机仍然存在,直到其删除空闲客户机超时开始。感谢您的帮助,但我相信我们正在使用
NetConnection
处理两种截然不同的事情,因此,这种方法对我不起作用。我不是用它来播放视频,而是用它连接到AMFPHP网关。我确实测试了您的代码片段,但该实例仍保留在内存中。唯一的区别是,现在内存中也有一个
字典的实例。我希望这个答案对其他使用
NetConnection
播放视频的人有用。我不认为它解决了我们的问题。我试过这样做,我也试过一些不同的变化。他们都不允许我的NetConnections从内存中清除。很抱歉,我在回答问题时遇到了一些问题。感谢您的回复,但代码都在外部类中。代码