What is garbage collection and how do you do it in ActionScript 3.0?

I have been programming in ActionScript for about 6 years, but never heard of the terms “garbage collection” until AS3 came out. Why should we worry about it now and never before? And what exactly? From what I read / heard, this has something to do with memory / leak management, etc. - and even this I do not understand, except that it has something to do with performance.

I recently launched a site for my artist friend, and it was done in AS3. I notice that it takes a lot of resources. Obviously, this is what I would like to improve. I guess this has something to do with the fact that garbage collection doesn't happen ?! Unfortunately, I have no idea where to start regarding this, as I feel that I need to better understand what it is and how to do it specifically in AS3.

For the curious, here is the URL: http://www.jeffperrott.com

+4
source share
6 answers

The garbage collector is part of the runtime (in your case, Flash or the AIR player), which cleans up unused memory. There has always been garbage collection in ActionScript, such as all scripting languages ​​(for example, javascript, perl, ruby, etc.), you just do not see that this has been much discussed for AS.

The main idea is that each created object takes up some memory, and your variables keep a reference to these objects. The memory of the object is not "freed" back to the pool of available memory until there are no references to it. The garbage collector keeps track of which objects have references to them, and at various intervals restores the memory of those who have null references (i.e. there are no variables pointing to it, so no code can even find it to use it). If there are any links *, the memory of the object cannot be fixed if any part of your code decides to use it in the future.

If your program seems to be leaking in memory (constantly growing, never stabilizing in size or shrinking), then you can put objects in a hash or array or some other collection object. This object obviously maintains a link to its contents, so these things are never deleted.

Note that in ActionScript it is easy to create leaks using closures as event handlers. If your handlers can access variables that are assigned but never will be null, these variables retain their references, and the objects they point to will not be garbage collected until an event handler is registered.

function registerHandler(neverReleased:Object) { ... addEventHandler(function (e:Event) { ... }); } 

Calling the garbage collector directly is almost always bad (tm); the garbage collector in Flash / Flex is very good. First, find out where your objects are stored and release them, letting the GC work on its own schedule.

* Except for round links , which is slightly different from this area of ​​the answer.

+6
source

Each time you use the "new" keyword to create an object, you put your application on a piece of memory [1]. So, let's say you make uint by writing var exampleUint:uint = new uint(); . ActionScript tells the computer "hey ... I need ... four bytes of memory" to which the computer responds "ok, use four bytes starting with [some memory address, for example 0x7B3208C1]" [2], so when you say var someString:String = "blah"; , you require a space in memory, fill it with some information (in this case it is "blah" ), create a label (in this case it is someString ) and bind a shortcut to this space in memory.

Now the label is not actually associated with the data itself, it is associated with a place in the memory containing the data. This should seem confusing because it is, but for certain reasons it causes a chaste feeling. All objects in the ActionScript reference , which means that the object contains the memory address of some piece of data, not the data itself. This contrasts with objects that are value , where the label is associated with the data itself. Do not worry about the details of value types, because it is not in ActionScript, so for your purposes, I include it strictly for contrast. Okay, embarrassed? You probably should be, because this entire paragraph is completely useless and perhaps even unnecessary, but try to keep it in the back of the head because it may have something to do with your problem.

Now that this label has disappeared (for example, it goes out of scope , now someString does not make sense), only the someString label is someString . So, for this example, if you say someString = null; , the string "blah" actually remains in memory, but the label someString does not refer to this piece of information, it refers to the memory address of a null object (again, details). We need a way to point to the computer "do you know that [whatSize] is a piece of memory that I claimed starting with [whateverAddress]? Well, I ended up with it now so that someone else could use that piece of memory." The Gabage collection is an automatic process to restore your recovered memory without having to worry about it yourself. In non-garbage collection languages, new has an add-on keyword that specifically frees the memory associated with the object [3], but ActionScript does not; you just take a piece of memory and forget about it.

Somewhere along the lines you could create another variable and refer to this piece of data var someOtherString:String = someString; , so we can’t just say "well, the someString label someString disappeared, so let's get rid of the data that it refers to," because we do not know for sure that someString is the only link to this data. The method in which this is done varies between languages ​​and garbage collection systems, but the main deal in ActionScript is this: from time to time (especially if Flash is currently taking up a lot of memory), the garbage collector scans all objects in the current SWF and finds all objects. which do not have a link [4]. So, for our previous example, if someString was the only thing that referenced the string "blah" and someString went out of scope, then "blah" n’t bound to any tags and therefore Flash was completely inaccessible. The next time the garbage collector starts up, it will find it and then report back to the system what it has done with this piece of memory.

Now the specific details of your particular problem will be hard to tell without looking at the source, but I can tell you that one of the problems that often cause problems is event listeners. Sometimes you can create a function and add it as an event listener. Now the event itself has a link to this function [5], therefore, if a function goes out of scope, it still refers to it, and the function does not receive a garbage collector (remember that functions are objects in ActionScript), you can either delete manual event handler by calling removeEventListener (I would not recommend it), or set the useWeakReference parameter when addEventListener () is called to true . A weak reference is not recognized by the garbage collector, so setting useWeakReference to true prevents the situation where you have a function that should be selected by the garbage collector, but this is not because someone refers to it as an event listener. Judging by the large number of mouseEvent listeners in your project, this could be a criminal. If you have Flex Builder, you can use the profiler to find out how many method closures you have; if they rise and never descend, this is probably your problem.

[1]: Keep in mind that this also applies to situations in which you create an object without using the new keyword, for example, if you have to write var exampleInt:int = 5; .
[2]: I chose uint because all uints are the same size, so I can confidently say that I know that it will be four bytes. The lines are different; they take up memory proportional to the number of characters they contain, so it would be a little more ambiguous to use String for both examples.
[3]: the ActionScript delete keyword is not for this purpose, so do not try to use it that way, although it would make logical sense, and it would be very useful. [4]: Flash uses a mark-and-sweep style strategy, more specific details of which can be read here . [5]: In fact, the bold type lies because the addEventListener method uses closure , but I have a rather poor understanding of this to start with so I cannot weld it in a normal person.

+2
source

I don't know anything about the implementation of AP3, but someone should post this :)

http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

Basically, you work with pointers (well, links) to data. A link outside the scope will be deleted. Whenever no links point to data, the data will be marked for garbage collection. Your GB stream (process or daemon) will free all the resources used to highlight marked data in time.

0
source

Usually, you or your development environment must manually process the memory at some point, wither, to create space for your application data in memory, or to clear memory from use as soon as your application is executed with it. If your production environment does not have a GC (garbage collector), you need to manually process the creations and delete the memory spaces for your variables and objects in your application.

An example is Native C ++. Before C ++ programmers can really do a lot with the application, they have to do the main work that concerns the memory itself. They request the OS for memory, add allocations, add objects and data to memory, then delete objects and data, unallocate memory, clean it up and release it to the OS again.

With GC, GC does everything that works for you. All you do is tell GC (usually by creating an object) that you plan to use memory, and GC calculates how much memory you need, asks the OS for it, allocates and adds your data. Then it checks from time to time if your application is still using this object. If this is not the case, it deletes the object, unallocates, cleans it and releases it back to the OS. All this is done for you, so that you, the programmer, can simply focus on your program. An example of this is VB 6.0 and C # / VB.NET.

EDIT: This is an extremely simplified explanation. Actually it is much more, but this answer should answer the main question asked here.

0
source

Addendum to Chadwick's answer:

If you add an AddHendler element to the image but don’t delete the EventHandler when the image is no longer displayed, the memory occupied by the image cannot be recovered by the garbage collector.

0
source

Just to help you understand why you haven't heard about this before, in previous versions of AS GC was deeply connected to the displayed list. Once you deleted an object from the scene, it no longer existed (along with any child objects), and any reference to them was nullified. This behavior, as you already know, is completely the opposite in AS3. Good luck

0
source

Source: https://habr.com/ru/post/1286536/


All Articles