Why does a closed NetConnection that has no event listeners or references stick around in memory?
Asked Answered
O

4

6

It seems that if flash.net.NetConnection is instantiated and connected to an HTTP URL (such as an AMFPHP gateway), that instance is never picked up by garbage collection even after it has been closed and the only reference is set to null.

On the other hand, if the instance is connected to null (as would be done when used to play video/mp3 files), the instance is cleared from memory.

To clarify, the following connection will stick around in memory:

var stickyConn:NetConnection = new NetConnection();
stickyConn.connect("http://myserver/amfphp/gateway.php");
stickyConn.close();
stickyConn = null;

Whereas, the following connection will be cleared from memory immediately:

var tempConn:NetConnection = new NetConnection();
tempConn.connect(null);
tempConn.close();
tempConn = null;

Some things I have already tried to solve this issue:

  • set the client to an empty object (since the default value of the client is the NetConnection itself)
  • before closing the connection, call connect(null)
  • after closing the connection, call connect(null) and close it again

Has anyone run into this issue before? Is there a solution to this?

Odey answered 8/2, 2013 at 20:4 Comment(7)
Have you tried that with Amfphp 2.1 or greater version?Turd
I have not; I'll give it a shot. Is this something you've tested yourself?Odey
I tested it out with the latest version of Amfphp (2.1.1) and it did not make a difference.Odey
I never really checked it out or gave it much of attention. Besides, it's a client-side problem, so you won't have server memory overload due to this. But I found it interesting and it would be cool to fix it.Turd
I'm not concerned about server memory. This is an AIR application and I'm concerned about the client side memory. Granted, a single instance of NetConnection consumes a marginal amount of memory; it just bugs me that it's hanging around when it shouldn't.Odey
Have you made sure there are no event listeners on your NetConnection? You've probably already done this, but it's worth double checking.Spalla
@mfa, yes, I've made sure. The code you see above (with no listeners) is the exact code that is exhibiting the leak.Odey
U
0

I have built heavyloaded FLV/Mp4 Players using AS3 quite often. When I am using a service like Akamai or Adobe's internal NetConnection Class I always keep in mind the client object.

the is the property of NetConnection on which ALL callback methods are invoked. The default is this NetConnection instance this. If you set the client property to another object, callback methods will be invoked on that object.

In this way you can easily understand how Garbage Collection was never really applied accross each component in the same way. So, where stickyConn = null; only stops the playback, since you never declared a Weak Reference, Garbage Collection has no clue what to look for.

I have had success with differrent methods based on the specific player:

Simply stating NetConnectionObj.client = this usually suffices. But what if your NetConnection is extended or implementing an interface? Simply use a null Dictionary object: var d:Dictionary = new Dictionary(true); . From here Garbage collection will recognize "d" as a weak reference and automatically dump it;

Hence, your snippet will look somewhat like this:
var Dc:Dictionary = new Dictionary(true);
NetConnection:NetConnection.client = Dc;

or some variation with the same intent.

I know this works, so reach out if you need help...

Underneath answered 13/2, 2014 at 11:28 Comment(2)
Thank you for trying to help, but I believe we are using NetConnection for two very different things, and for that reason, this method did not work for me. I'm not using it to play a video, I'm using it to connect to an AMFPHP gateway. I did test your snippet, and the instance is still sticking around in memory. The only difference is that now, there's an instance of a Dictionary hanging around in memory as well. I hope that this answer will come in handy for others who are using NetConnection for video playing.Odey
I don't think it's solving our problem. I tried doing that, and I've also tried a few different variations of it. Neither have allowed my NetConnections to get cleared out of memory.Harebell
U
0

I may have been vague with the last answer in regards to GC and Dictionary Objects. Please take this snippet into consideration. I wrote it quickly but I try to explain the Concept of what solves your problem; mainly since I have dealt with it before:

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;
    }
}
Underneath answered 14/2, 2014 at 3:33 Comment(1)
Sorry, I'm having a little bit of trouble following the answer.Harebell
A
0

I'm not sure but Your example seems to suggest you are declaring your vars on stage / frame.

close(); is all you need for this to work HOWEVER.... from what I have found with NetConnection it for some reason unless all vars / functions are declared in an External class eg. public vars public function, It stays in memory even after using close();

Pulled out my hair figuring this out with an audio streaming project. However once I moved all coding to an external class, close(); actually closed the connection.

If your code is on a frame on stage or within MC I would create a class and declare vars & functions in said External Class.as and for some stupid reason it works.

Hope this helps.

Athalia answered 2/5, 2016 at 18:57 Comment(1)
Appreciate the response, but the code is all in an external class. The code above is a bare-bones example to demonstrate the issue at hand.Odey
V
-1

Are you using a NetStream object and not disposing of it when finished? I only ask because I rarely see a NetConnection without a NetStream object far behind it.

Versicle answered 14/2, 2013 at 22:8 Comment(3)
There is no NetStream object involved. NetStream is used in conjunction with NetConnection for streaming video/sound. In this case, the NetConnection is used to connect to an AMFPHP gateway.Odey
While not a solution to the specific problem, I found this answer helpful. It's nice to have the list of 'usual suspects' to look into when troubleshooting any issue.Spalla
The question deals with the fact that are no leftover references or anything in the client, not even event listeners. The NetConnetion is closed, its references are thoroughly removed, everything. The only thing I've noticed is that the FMS still seems pretty determined to assume that the client is still present, until its remove idle client timeout kicks in.Harebell

© 2022 - 2024 — McMap. All rights reserved.