AS3: do anonymous objects get garbage collected? - actionscript-3

I do this a lot to configure new instances of classes
var myVar = new MyClass({param:1,param2:true,param3:"hello"});
Does this anonymous object gets garbage collected?
Would it be better to create and destroy the object after using it?
var myConfig:Object = {param:1,param2:true,param3:"hello"}
var myVar = new MyClass(myConfig);
myConfig = null;

I believe you are referring to "object literals", which should be garbage collected.
Flash uses two approaches to garbage collection - reference counting and mark and sweep.
If not caught by reference count, it should ultimately be released by mark and sweep.
Reference Counting
Each object on the heap keeps track of the number of things pointing to it. Each time you create a reference to an object, the
object's reference count is incremented. When you delete a reference,
the object's reference count is decremented. If the object has a zero
reference count (nothing is pointing to it), it is added to the Zero
Count Table (ZCT). When the ZCT is full, the stack is scanned to find
any references from the stack to an object on the ZCT. Any object on
the ZCT without a stack reference is deleted.
One of the problems of deferred reference counting is circular references. If ObjectA and ObjectB refer to each other but no other
objects in the system point to them, they will never have a zero
reference count and will therefore never be eligible for garbage
collection using reference counting. This is where mark and sweep
garbage collection helps.
Mark/Sweep
Applications that run in Flash Player or AIR have multiple GCRoots.
You can think about a GCRoot as the trunk of a tree with the objects
of the application as the branches. The Stage is a GCRoot. Loaders are
GCRoots. Certain menus are GCRoots. Every object that is still in use
by the application is reachable from one of the GCRoots within the
application. GCRoots are never garbage collected.
Every object in an application has a "mark bit." When the Mark phase
of garbage collection begins, all of those mark bits are cleared. The
MMgc keeps track of all GCRoots in the application. The garbage
collector starts from those roots, traces through each object and sets
the mark bit for every object it reaches. Any object that is no longer
reachable from any of the roots is no longer reachable from anywhere
in the application – its mark bit does not get set during the Mark
phase. Once the collector is done marking all of the objects it finds,
the Sweep phase begins. Any object that doesn't have a set mark bit is
destroyed and its memory reclaimed.

Related

What "time precise" garbage collection algorithms do exist?

Which garbage collection algorithms can recognize garbage objects as soon as they become garbage?
The only thing which comes to my mind is reference counting with an added cycle-search every time a reference count is decremented to a non-zero value.
Are there any other interesting collection algorithms which can achieve that? (Note that I'm asking out of curiosity only; I'm aware that all such collectors would probably be incredibly inefficient)
Though not being a garbage collection algorithm, escape analysis allows reasoning about life-time of objects. So, if efficiency is a concern and objects should be collected not in all but in "obvious" cases, it can be handy. The basic idea is to perform static analysis of the program (at compile time or at load time if compiled for a VM) and to figure out if a newly created object may escape a routine it is created in (hence the name of the analysis). If the object is not passed anywhere else, not stored in global memory, not returned from the given routine, etc., it can be released before returning from this routine or even earlier, at the place of its last use.
The objects that do not live longer than the associated method call can be allocated on the stack rather than in the heap so they can be removed from the garbage collection cycle at compile time thus lowering pressure on the general GC.
Such a mechanism would be called "heap management", not garbage collection.
By definition, garbage collection is decoupled from heap management. This is because in some environments/applications it is more efficient to skip doing a "free" operation and keeping track of what is in use. Instead, every once in a while, just ago around and gather all the unreferenced nodes and put them back on the free list.
== Addendum ==
I am being downvoted for attempting to correct the terminology of heap management with garbage collection. The Wikipedia article agrees with my usage, and what I learned at university, even though that was several decades ago. Languages such as Lisp and Snobol invented the need for garbage collection. Languages such as C don't provide such a heavy duty runtime environment; instead the rely on the programmer to manage cleanup of unused bits of memory and resources.

AS3 memory leak

I've been working on a library, and have run into a problem with application memory.
I created a class called FileManager which allows the user to call a function called loadNewFiles - this function opens a multi-file selection dialog and stores each FileReferenceList in a vector. I can call the removeList function at any time and remove that list and clear any memory and listeners allocated to that list, so all's well there.
I created another class called UploadManager, which takes an array of FileReference objects and uploads them to a URL via the uploadFiles function. The memory leak appears to be here. When you call this function, it adds the appropriate event listeners and calls the upload function. If the upload fails or the upload is finished, it removes the listeners and clears the vector it has been waiting in.
after the upload manager finishes uploading the files, I call the removeFiles function in FileManager (which, remember, worked perfectly before) and... Nothing happens. The files are removed from both vectors, the listeners are removed from both files, but the memory stays allocated. This obviously has potential to cause problems along the road, as there's no limit to the number of files, uploads, etc. available through the library.
classes:
FileManager
UploadManager
Implementation
It sounds like from your example that the UploadManager still has a reference to the files either from the vector passed into uploadFiles, or some other object in the game still has a reference.
Also note, System.gc() only works on the debug version of the flash player.
So you can't depend on it for an architectural design choice. It works for unit testing memory intensive operations when you need to see the consumption of ActionScript memory "on demand".
In a production product, the ActionScript Virtual Machine is very active in detecting when and where to garbage collect. Most would say it happens right when you don't want it to.
Try profiling the application and looking at the "cumulative instances" vs. "instances", as well as the "cumulative memory" vs. "memory" for the objects in question (i.e. FileReference).
You can force garbage collection during runtime in the Profile View to get a realistic idea of how much memory is actually freed when garbage collection takes place in the Release version.

Does Flash Render items that are out of the stage bounds?

Is flash smart enough to "hide" PIXELS that aren't on the stage, in order to decrease memory usage? Or I must do it manually, if it decreases the memory usage at all?
Flash does not render objects that aren't on the stage (as per http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3e.html).
However I think you may be mixing up two different issues.
One issue is CPU/GPU performance - for this there is no need to worry about off-stage objects as Flash does not waste time rendering display objects that are outside the stage bounds.
The other issue is memory usage. Every object that you create takes up some memory whether or not it is visible on the screen. Flash has a garbage collector that will periodically dispose of unused objects, however "unused objects" means an object that isn't referenced by any other object so if you are having memory issues you will have to manually clean up objects by removing event listeners, nulling references etc.
There's nothing like that available to decrease memory usage. If it's visible on your monitor, it needs to be rendered by Flash and have a place in memory storing the pixel colour.
Although Flash is very fast these days, especially with hardware acceleration. So you shouldn't worry too much about performance, there's a lot of bang for your virtual buck with AS3. I'd bet all of my virtual dollars on it.
Flash will store all bitmaps, movieclips in fact all objects in memory as expected. If you have a large bitmap which is larger than the stage, it still occupies memory regardless of you only showing a portion of it.
If you have multiple bitmaps or movieclips that may move off the stage and no part of them are visible, then the only way to recover memory is to make sure the object is dereferenced and set to null.
myMovieClip = null;
Prior to setting to null you would also have to make sure that nothing else is referencing the object, for example it can't be stored in an array or have any event listeners attached to it so therefore:
myMovieClip.removeEventListener(Event.WHATEVER, eventHandler);
For bitmapdata objects you would need to call dispose first before setting to null:
myBitmapdata.dispose();
myBitmapdata = null;
This then allows the GC to recover memory when it chooses, unless you are using AIR which means you may request a gc call yourself:
System.gc();
If you are developing in Flash Builder, the best practice is to regularly profile your application and hit the button to force a gc call. You can then see which objects are persisting in memory and locate the references which are causing the memory leaks.

AS3 Memory management when instantiating extended classes

I'm developing an AS3 application which has some memory leaks I can't find, so I'd like to ask some newbie questions about memory management.
Imagine I have a class named BaseClass, and some classes that extend this one, such as ClassA, ClassB, etc.
I declare a variable:
myBaseClass:BaseClass = new ClassA();
After a while, I use it to instantiate a new object:
myBaseClass = new ClassB();
some time after
myBaseClass = new ClassC();
and the same thing keeps happening every x millis, triggered by a timer.
Is there any memory problem here? Are the unused instances correctly deleted by the garbage collector?
Thanks!
Assuming you have no other references to the instance (or, possibly, its contents), the garbage collector will clean them up. However, the time before cleanup is, as far as I know, indeterminate (there might be some hard timeline in use, but I've never seen it documented). If you're creating a huge number of instances, you might use up a lot of memory before the first ever gets cleaned up.
There is an AS call (the name of which escapes me at the moment) to force a GC run, but it shouldn't normally be necessary. If you find it necessary, you almost certainly need to rethink how your application works.
If myBaseClass is the only stored reference to
new ClassA()
and you assign something else to myBaseClass
new ClassB()
then there will be no reference pointing to ClassA and the garbage collector should find it when it runs.
However, if you give myBaseClass to a library or class that stores its own reference to that object, when you reassign myBaseClass there will still be a reference pointing to the ClassA and the garbage collector will not clean it up, creating a memory leak. Normally a well written library will provide you with a way to remove the reference. e.g.
var child:Sprite = new Sprite()
// one reference to the new Sprite
stage.addChild(child); // assume stage stores reference
// two references to the new Sprite
/**
* assume the following:
*
* child = null;
*
* one reference would still remain in stage
* garbage collector will not clean up the sprite
*/
stage.removeChild(child); // assume stage clears reference
// one reference left
child = null;
// no reference to the sprite, garbage collector will clean it up
Hope this clears things up a bit. Essentially you want to keep track of how many references there are to an object, if you suspect it to be leaking memory.
I know that FlashDevelop has a profiler that is quite useful for finding these bugs. Also, you need to know that when the garbage collector runs... it will free up memory and give a saw tooth pattern to your memory profiler.
Good example code for demonstrating profiling in Actionscript 3
AS3 Memory Leak Example

Can garbage collection coexist with explicit memory management?

For example, say one was to include a 'delete' keyword in C# 4. Would it be possible to guarantee that you'd never have wild pointers, but still be able to rely on the garbage collecter, due to the reference-based system?
The only way I could see it possibly happening is if instead of references to memory locations, a reference would be an index to a table of pointers to actual objects. However, I'm sure that there'd be some condition where that would break, and it'd be possible to break type safety/have dangling pointers.
EDIT: I'm not talking about just .net. I was just using C# as an example.
You can - kind of: make your object disposable, and then dispose it yourself.
A manual delete is unlikely to improve memory performance in a managed environment. It might help with unmanaged ressources, what dispose is all about.
I'd rather have implementing and consuming Disposable objects made easier. I have no consistent, complete idea how this should look like, but managing unmanaged ressources is a verbose pain under .NET.
An idea for implementing delete:
delete tags an object for manual deletion. At the next garbage collection cycle, the object is removed and all references to it are set to null.
It sounds cool at first (at least to me), but I doubt it would be useful.
This isn't particulary safe, either - e.g. another thread might be busy executing a member method of that object, such an methods needs to throw e.g. when accessing object data.
With garbage collection, as long as you have a referenced reference to the object, it stays alive. With manual delete you can't guarantee that.
Example (pseudocode):
obj1 = new instance;
obj2 = obj1;
//
delete obj2;
// obj1 now references the twilightzone.
Just to be short, combining manual memory management with garbage collection defeats the purpose of GC. Besides, why bother? And if you really want to have control, use C++ and not C#. ;-).
The best you could get would be a partition into two “hemispheres” where one hemisphere is managed and can guarantee the absence of dangling pointers. The other hemisphere has explicit memory management and gives no guarantees. These two can coexist, but no, you can't give your strong guarantees to the second hemisphere. All you could do is to track all pointers. If one gets deleted, then all other pointers to the same instance could be set to zero. Needless to say, this is quite expensive. Your table would help, but introduce other costs (double indirection).
Chris Sells also discussed this on .NET Rocks. I think it was during his first appearance but the subject might have been revisited in later interviews.
http://www.dotnetrocks.com/default.aspx?showNum=10
My first reaction was: Why not? I can't imagine that you want to do is something as obscure as just leave an unreferenced chunk out on the heap to find it again later on. As if a four-byte pointer to the heap were too much to maintain to keep track of this chunk.
So the issue is not leaving unreferenced memory allocated, but intentionally disposing of memory still in reference. Since garbage collection performs the function of marking the memory free at some point, it seems that we should just be able to call an alternate sequence of instructions to dispose of this particular chunk of memory.
However, the problem lies here:
String s = "Here is a string.";
String t = s;
String u = s;
junk( s );
What do t and u point to? In a strict reference system, t and u should be null. So that means that you have to not only do reference counting, but perhaps tracking as well.
However, I can see that you should be done with s at this point in your code. So junk can set the reference to null, and pass it to the sweeper with a sort of priority code. The gc could be activated for a limited run, and the memory freed only if not reachable. So we can't explicitly free anything that somebody has coded to use in some way again. But if s is the only reference, then the chunk is deallocated.
So, I think it would only work with a limited adherence to the explicit side.
It's possible, and already implemented, in non-managed languages such as C++. Basically, you implement or use an existing garbage collector: when you want manual memory management, you call new and delete as normal, and when you want garbage collection, you call GC_MALLOC or whatever the function or macro is for your garbage collector.
See http://www.hpl.hp.com/personal/Hans_Boehm/gc/ for an example.
Since you were using C# as an example, maybe you only had in mind implementing manual memory management in a managed language, but this is to show you that the reverse is possible.
If the semantics of delete on a object's reference would make all other references referencing that object be null, then you could do it with 2 levels of indirection (1 more than you hint). Though note that while the underlying object would be destroyed, a fixed amount of information (enough to hold a reference) must be kept live on the heap.
All references a user uses would reference a hidden reference (presumably living in a heap) to the real object. When doing some operation on the object (such as calling a method or relying on its identity, wuch as using the == operator), the reference the programmer uses would dereference the hidden reference it points to. When deleting an object, the actual object would be removed from the heap, and the hidden reference would be set to null. Thus the references programmers would see evaluate to null.
It would be the GC's job to clean out these hidden references.
This would help in situations with long-lived objects. Garbage Collection works well when objects are used for short periods of time and de-referenced quickly. The problem is when some objects live for a long time. The only way to clean them up is to perform a resource-intensive garbage collection.
In these situations, things would work much easier if there was a way to explicitly delete objects, or at least a way to move a graph of objects back to generation 0.
Yes ... but with some abuse.
C# can be abused a little to make that happen.
If you're willing to play around with the Marshal class, StructLayout attribute and unsafe code, you could write your very own manual memory manager.
You can find a demonstration of the concept here: Writing a Manual Memory Manager in C#.