AS3 garbage collection and memory management

Source: Internet
Author: User
Tags root access

GC and Memory leak Independent

Garbage collection, this is a traditional topic that has been discussed by countless people.

Action Script uses a memory management mechanism similar to Java, and does not instantly reclaim the memory of discarded objects, but instead performs a single GC (Gabage Collection) operation at a specific time to release the memory of discarded objects. Avoid repeated judgments about the performance issues that need to be recycled.

Note, however, that this is only the time to decide on recycling, not what to recycle. This deferred memory recovery is a surface phenomenon, no matter when the GC is executed, the memory that can be reclaimed can eventually be recycled, and cannot be recycled. The only effect is that, because recycling is deferred, you cannot visually see the process of recovering memory from an object being discarded because it is delayed.

However, this is irrelevant for resolving a memory leak.

A memory leak means that when you destroy an object, the memory it consumes cannot be recycled, which leads to a smaller, more usable memory that eventually overflows, causing the system to crash in a memory-intensive environment. There are many reasons for this, but they are generally overlooked by developers and do not provide sufficient basis for the system to destroy objects.

Performing a GC is not related to a memory leak, but if you do not perform a GC before the test, you will not see the actual amount of non-recoverable memory at that time, and memory leaks refer to an increase in the amount of non-recoverable memory. Therefore, testing for memory recycling will be inseparable from GC methods. There is no point in a test case that does not use a GC method, because it is doped with the occasional (when the GC is executed). Many absurd test results are caused by not performing GC in the right place.

Although Flash Player does not have a manual GC for publishing status, the debug version is available, just to let us test it. In addition, the following HACK code can also trigger a GC during the release phase.

Try {       new localconnection (). Connect ("GC" );        New LocalConnection (). Connect ("GC" );       Catch (E:error)     {      }

But again I emphasize that invoking the GC is just for testing. It doesn't make sense to call the GC in the actual product (except for the timing of the GC), so if your program has a memory leak, it has nothing to do with GC, so don't waste your precious time and energy in this place.

Automatic GC is triggered only when memory is requested

The GC for AVM2 is triggered each time the memory is requested, based on the current memory consumption. Requesting memory is a necessary factor. So, if you have not been applying for memory operation, even if the memory reaches a high value, it will not be GC.

This is indeed an unreasonable place. However, in the actual environment, it is very rare that the memory is not requested, even if it occurs, it may not be in the high value of memory at that time. This situation is mainly in the test environment, causing some people to suspect that the function of automatic GC is normal. In fact, this is not necessary.

Conditions for garbage collection in Flash

In AVM2, except that special BitmapData must call Dispose in order to reclaim memory, the other part is to use the reference counting method and the mark clear method as a means of judging whether the memory should be recycled, and does not provide an active recycling API, detailed section please see this log, I will not repeat.

Http://www.cnblogs.com/cos2004/archive/2010/11/07/1870980.html

So, you want to reclaim an object as long as it is guaranteed that no object is referencing it, and that his method is not treated as an event function--or that he has no connection to the rest of the program, and that it satisfies the standard of reference counting and is bound to be recycled. The way to do this is generally said "execute Removechild,removeeventlistener, set his reference to null".

However, the requirement to actually reclaim an object is not as strict as that of the FP, except for the reference counting method, which also includes the tag cleanup method. The markup cleanup method is to iterate from the root object of the program (stage, static properties, active Timers and loaders, Externalinface.callback) at the first level, so long as it is not traversed, even conditions that do not satisfy the reference counting method can be recycled. For example, two objects are referenced to each other, but are not related to the outside world, form an island, they can be recycled, even though they are referenced by each other so that the number of references is not 0. Compared to simple reference counting, this approach can really find the actual idle objects that are no longer accessible. So, you can see a lot of people's code is actually not set NULL, or even no removeeventlistener, it can be normal recovery, write less code can make the program more concise, to all conform to the conditions of the mark clear, will be very tired.

"Can not be root access", this is very ambiguous, basically can not be used as a basis for judgment. So I'll give you a few specific examples to show what the situation is in compliance with the requirements of the mark removal method.

First, make it clear that the tag cleanup method is only based on the ability to be accessed by the root and does not need to be concerned about the number of times it is referenced.

  • The mutual reference to a property is very clear, and it is generally an object that contains a number of attributes, so the object can naturally maintain a reference to its properties. If this class is not recycled (can be accessed by the root), all of his properties will not be recycled. Similarly, if the class can be recycled (it cannot be accessed by the root), it will not prevent the property from being recycled. So you don't have to set all of the properties to null unless you want to reclaim the memory of its properties when the object exists, which is basically nonexistent.
  • A static property is a special case. The static property itself is the root, so you have to set it to null to be able to be recycled, no other way.
  • As for the objects in the display list. Since the root (stage) can use Getchildat to access all of its child objects, you will certainly not be recycled as long as you are in the display list. However, if the parent object of the display object is no longer displayed in the list, its sub-objects are not related to the parent-level object, because it cannot be accessed by the stage. So you don't need to removechild all the objects in each layer, but only removechild the parent of the highest level.
  • A.addeventlistener ("event", B.handler), after adding an event like this, you can think of B.handler as a property of a (because a can call B.handler when needed), which also conforms to the principle of attribute mutual reference. But events are more difficult to judge than attributes, because there are a lot of cases of referencing each other. There are three scenarios:
    1. Listening to your own events is equivalent to saving your own references with your own attributes, and nothing will prevent you from being recycled.
    2. Listen to your own child objects (attributes or children) for their own events. Because child objects are inherently self-sustaining references, even if they maintain your references, they only form a loop. Once you're out of touch with the stage, the sub-objects will also be out of touch, and of course not be able to prevent you from being recycled. This is rare, unless a child object can maintain a reference (such as being saved in a static property) for some reason alone.
    3. Listen to your own events on your parent object (parent or stage). Because this makes you a property of the parent object, you will not be recycled as long as either the parent or the stage is not recycled. Especially the stage, it certainly will not be recycled. This situation will generally lead to the inability to recycle, it must be removeeventlistener.

In general, it is important to pay attention to the stage,parent of the event monitoring, other situations generally will not hinder the recovery. And most of the stage,parent monitoring is a variety of mouse, keyboard events. The number is not much, specifically note that this can eliminate most of the memory leaks caused by the event.

In fact, memory leaks are not easy to come by. According to normal programming habits, only listening to the stage event will cause unexpected leaks, which can generally be recovered smoothly. This is more convenient than having to recycle the memory manually every time.

Only BitmapData here is the exception. In addition to complying with the rules above, to reclaim its memory, you must call the Dispose method manually, and people who are accustomed to automatic recycling will be tired. It is important to note that the BitmapData property of the Bitmap object needs to be destroyed manually, and the Loader loaded bitmap needs to be manually destroyed when you draw a tiled image with a generated bitmap as a bitmap fill. This bitmap must also be destroyed after the image is destroyed (so you must keep a reference to the bitmap). BitmapData is 32 bits without any compressed image, any size will be very large, do not handle their recovery, a BitmapData leak can top your tens of thousands of complex objects leaked.

If there is a very obvious memory leak, most of the time it is a bitmap leak. So before you study the reference counting method and the tag cleanup and GC, make sure that the bitmap parts are not faulty.

Exceptions to weak references

Weak references change the rules for garbage collection. If you use a weak reference, AddEventListener will not affect object recycling, even if you add listening to the stage, it will not cause you to be recycled. But this is also a disadvantage, because sometimes you just want to use reference to limit the collection of objects, using weak references will make this object can be recycled and sometimes not recycled. Although rare, it is difficult to find a mistake that is not easy to reproduce once it appears. Therefore I do not recommend using weak references.

Weak references have only two places in the AVM2:

    • One is the 5th property of the AddEventListener, named Userweakreference, set to True, the listener event will not affect object recycling.
    • One is the Dictionary constructor parameter, named Weakkeys, set to True, and the key can be reclaimed even if Dictionary exists when the key is a complex object. Note that here is the key, not the value, the value is not to enjoy the weak reference treatment. This attribute is also well written and is Weakkeys.

How to find memory leaks

Flash Builder provides a profiling tool that can help us find memory leaks. Most of the situation can help us solve the problem. You can view the following articles:

Http://blog.csdn.net/bbmjfpig/archive/2010/12/30/6107347.aspx

The key point is that detecting a memory leak should be "create, sample, destroy, recreate, sample," and then look at the leak in two samples of the comparison data. Because objects have cached data for the first time they are created, they are not designed to be recycled as objects are destroyed, such as the cache of class definitions, such as skins. They are created only once, and the leaks we see are not the same thing.

Mandatory GC can be executed if necessary

Because each GC consumes performance, the more objects you have, the slower the GC. I understand that Flash player disables the release version of System.GC () to avoid misuse by developers, but sometimes we do need to manually control GC timing because the GC process can get Flash Player stuck if it encounters a large number of recyclable objects.

For example, we need to recycle the memory when switching the screen, when the card is not visible, but not when the animation is played back and then let the animation live. Alternatively, we will periodically perform a GC when necessary to share the time required by the GC. So it is also a choice to force a GC with the HACK method at this time. Of course, this has nothing to do with memory leaks.

The design of this place of Flash Player is especially bad. It does not support step GC itself, and there is no way to avoid card problems once GC. As a result, the timing of GC is not yet controlled ...

Trace remaining memory

In the test, FLASH does have an infinite amount of memory increase, the reason is unknown. I throw 500,000 objects in an array, and it does add up to 1M of memory (if not thrown in the array), but this is a small number, but it takes 50 million objects to reach the visible 100M memory, which is difficult to achieve under normal circumstances.

However, some people say that this is only the object destroyed and the memory is not completely released, in fact, finally can be completely released. Or because of the imprecision of the totalmemory. I'm not sure about that.

But even if this is really a flashplayer BUG, it doesn't hurt.

AS3 garbage collection and memory management

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.