为什么在内存中没有事件监听器或引用的封闭NetConnection?

时间:2013-02-08 20:04:08

标签: actionscript-3 flash memory-management memory-leaks amfphp

似乎如果flash.net.NetConnection被实例化并连接到HTTP URL(例如AMFPHP网关),那么即使关闭了垃圾收集并且唯一的引用设置为空。

另一方面,如果实例连接到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)并再次关闭

之前是否有人遇到此问题?有解决方案吗?

4 个答案:

答案 0 :(得分:0)

我经常使用AS3构建重载的FLV / Mp4播放器。当我使用像Akamai或Adobe的内部NetConnection类这样的服务时,我始终牢记这一点 client object

  
    

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

  

通过这种方式,您可以轻松地了解Garbage Collection从未真正以相同的方式应用于每个组件。因此,stickyConn = null;仅停止播放,因为您从未声明过弱参考,垃圾收集无法找到要查找的内容。

我根据特定玩家的不同方法取得了成功:

  

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

     
    

因此,您的代码段看起来有点像这样:
var Dc:Dictionary = new Dictionary(true);
NetConnection:NetConnection.client = Dc;

         
      

或具有相同意图的某些变体。

    
  

我知道这有效,所以如果你需要帮助就伸手去拿......

答案 1 :(得分:0)

关于GC和Dictionary Objects的最后一个答案我可能一直含糊不清。请考虑此片段。我写得很快,但我试着解释解决问题的概念;主要是因为我之前处理过它:

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;
    }
}

答案 2 :(得分:0)

我不确定,但你的例子似乎暗示你在舞台/帧上声明你的vars。

接近();这就是你需要的所有工作但是...... 从我在NetConnection中找到它出于某种原因除非所有变量/函数都在外部类中声明,例如。公共事业公共职能, 即使在使用close();

之后它也会保留在内存中

通过音频流项目拉出我的头发。 但是,一旦我将所有编码移动到外部类,close();实际上关闭了连接。

如果您的代码位于舞台上或MC内的框架上,我会创建一个类并声明vars&所述外部Class.as中的函数和一些愚蠢的原因它起作用。

希望这有帮助。

答案 3 :(得分:-1)

您是否正在使用NetStream对象并在完成后不进行处理?我只是问,因为我很少看到没有NetStream对象的NetConnection。