您的位置:首页 > 其它

Understanding Memory Leaks in ActionScript (Adobe Flex)

2008-12-24 21:25 471 查看
Thanks go to Danny of TheGoldHold.com for a bunch of this information!

In ActionScript, there is no method to manually completely remove an
object from memory. That task is soley the responsibility of the Flash
Player's garbage collector (GC). The GC operates autonomously, and
beyond the "Force GC" button in the Flex Builder memory profiler, there
is no method to cause the GC to run. Therefore, memory leaks in Flex
can be hard to understand and debug.

I have created a MemoryLeakTest project
in Flex Builder that show examples that are and are not memory leaks.
The project contains three applications, two with memory leaks and one
with out. Each sample application adds and removes a single
sub-component 100 times per second. This forces the garbage collector
to run, and easily shows when a memory leak occurs. The source code
contains comments that explain the memory leaks, and how to avoid them,
but I'll go over them briefly here as well.

Flash Player Memory Allocation

Memory allocation speed inside the Flash player runtime is limited
by the browser. Therefore, instead of making a large number of small
requests for memory, flash player makes a small number of requests for
large chunks of memory. Memory deallocation is also a slow process, so
flash player is reluctant to give up memory; though it will do so as
necessary.

Garbage Collector Specifics

Objects are garbage collected only when they have no other objects
that contain strong references. Flash Player's runtime keeps a
reference table that is updated each time a reference is made between
two objects. The Garbage Collector simply uses that table to determine
which objects are completely de-referenced.

The Garbage Collector (GC) runs directly before additional memory is
requested. This way flash player can gain the memory resources used by
garbage objects, and can re-evalute the need to allocate additional
memory; possibly saving time. It is important to note that GC does not
run immediately when an object is completely de-referenced. So, even
though you've completely de-referenced an object it can and probably
will stay in memory.

Identifying Memory Leaks

Flex Builder 3 Pro includes a "Profiler" tool that can be used to
identify memory leaks. In that tool is a "Force Garbage Collection"
button. When your application is being profiled, simply click that
button and monitor the "Live Objects" list. If you believe you have
complete removed and dereferenced an object, its number of "instances"
should have be reduced.

Use the "Cumulative Instances" to determine how many instances of
that object were ever created, and the "Instances" column to determine
how many of those instances still exist. If after creating and removing
an object, then running "Force GC", those numbers are still the same,
you probably have a memory leak.

The "Memory Usage" chart is another way to determine whether a
memory leak exists; but only for small applications. The red line
represents the maximum memory use, and the blue line represents the
current memory use. If the blue line and red line never separate, you
have a memory leak.



Bad Memory Usage



Good Memory Usage

Memory Leaks by Reference

Because the garbage collector determines which objects to free by
their references, it is important for the developer to keep up with
what references they have created. A very simple example of this is
creating a reference from a parent object to a child object.

In the following example, a childObject is created, and then a
second reference is made to that childObject. Because that second
reference still exists at the end of this code, that childObject will
never be freed; unless the parent object is garbage collected.

private var childObject:Object = {test: 'test'};

private var secondReference:Object = childObject;

childObject = null;


Memory Leaks by Event Listeners

Incorrect use of EventListners are the number one cause of memory
leaks in ActionScript. EventListeners push references of the callback
object into an array on the target object. That reference keeps the
Garbage Collector from destroying the call back object. There are a few
exceptions to this rule. These do not block garbage collection:

Weak References
Self References
References to Child Objects

Weak references are created by setting fifth argument of
"addEventListner" to "true". By default, eventListeners use strong
references. Note that using a weak referenced eventlistner, and then
having no other reference to an object means that object will be
garbage collected, so be careful!

An example of a weak reference event listener.

someObject.addEventListener(MouseClick.CLICK, handlerFunction, false, 0, true);


Self references are simply references by an object to itself. A
common example is adding an eventListener to a component, and handling
it inside of that component.

An example of a self reference event listener.

this.addEventListener(MouseClick.CLICK, handlerFunction);


Child references are references to a child object. When a parent
object is garbage collected, that destroys the references to the child
object. So usually, this means the child object will also be garbage
collected (unless outside references to that child object exist).
Therefore, it is safe to add eventListeners to an immediate child
object and not worry about memory leaks. You should note that the child
object will not be freed until the parent object is freed!

An example of a childObject event listener:

private var childObject:UIComponent = new UIComponent;

addChild(childObject);

childObject.addEventListener(MouseEvent.CLICK, clickHandler);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: