Understanding Memory Leaks in ActionScript (Adobe Flex)

本文深入探讨了Flex中常见的内存泄漏问题及其原因,包括由引用和事件监听器导致的内存泄漏。文章通过实例演示如何识别并解决内存泄漏,并介绍了垃圾回收机制的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

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:

  1. Weak References
  2. Self References
  3. 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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值