`

flex 内存回收经典文章(2)

阅读更多

Caching

Let’s assume you know in advance how many renderers are needed. One way to solve the memory leak is to create a cache of renderers at startup.

1
2
3
4
5
6
7
private var cache:Array = new Array();
 
private function initRenderers():void {
    for (var i:int = 0; i < 200; i++) {
	renderers.push(new MyRenderer());
    }
}

We can then modify our loadData method like this:

1
2
3
4
5
6
7
8
9
10
11
private function loadData():void {
    container.removeAllChildren();
    var array:Array = getData();
 
    for (var i:int = 0; i < array.length; i++) {
	var rend:MyRenderer = cache[i];
	rend.data = array[i];
  	container.addChild(rend);
	i++;
    } 
}

As you can see in the code we don’t create new renderers but we look for one in the cache. There are cases when you don’t know in advance which data are returned from the server and then you don’t know how many rendereres you need. In this case you need a dynamic cache.

Dynamic cache

Dynamic caching is based on an elastic mechanism. You have a place where you can look for a renderer: if there is one in the cache, that is returned, otherwise a new one is created temporarily. Better to see some code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MyRendererCache extends Object {
 
    private static var cache : ArrayCollection = new ArrayCollection();
 
	public function MyRendererCache() {
	    super();
            for ( var x : Number = 0; x < 20; x ++ ) {
		cache.addItem( new MyRenderer() );
	    }
	}
 
	public static function getRenderer() : MyRenderer {
	    var renderer : MyRenderer;
 
	    if ( cache.length <= 0 ) {
		renderer = new MyRenderer();
	    } else { 
		renderer = cache.removeItemAt( 0 ) as MyRenderer;
	    }
 
	    return renderer;
        }
 
        public static function setRenderer( renderer : MyRenderer ) : void {
	    cache.addItem( renderer );
        }		
}

In the constructor you populate the cache with the minimu number of renderers, say 20 (lines 7-9). The cache has two static methods, getRenderer and setRenderer. The first is used to obtain a renderer, the second to give it back when done. If you look and lines 15-16 the cache returns a new renderer when the cache is empty. This way the number of renderers in memory can grow beyond the minimum number set in the constructor, but just temporarily, since the GC will delete them when not referenced anymore.
An important issue is related to the setRenderer. When you don’t need a renderer anymore you have to return it back to the cache, otherwise we fall again in a memory leak as explained above. To achieve this we exploit the remove event of the renderer. The remove event is triggerer whenever a UI element is removed from the display list. For example when we call removeAllChildren() such event is triggered for each renderer.
We can modify the renderer like this:

1
2
3
4
5
6
7
8
9
10
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" 
    borderStyle="solid" width="200" 
    remove="onRemove()"
    >
 
    private function onRemove():void {
	MyRendererCache.setRenderer(this);
    }
....
</VBox>

If you now run the profiler you will notice that memory grows until a given point and then keeps stable as in the figure below.

Stable Memory Consumption

Congratulations! You have solved the memory leak!

Suggesting the GC

Besides favoring the job of GC Adobe has allowed programmers to suggest the intervention of the GC. The command is in the flash.system package and it is System.gc(). By documentation this “Forces the garbage collection process” but in my experience it is just a vague suggestion of intervention. It can solve some situation, so it is worth trying it at the beginning, when you need a quick way to save some memory.




Full screen slides available here.

The source code of this post is available under the new BSD license.

References

分享到:
评论

相关推荐

    Flex虚拟机内存管理机制及防止内存泄漏

    本篇文章将深入探讨Flex虚拟机的内存管理机制以及如何预防和处理内存泄漏问题。 内存管理在任何软件开发中都至关重要,尤其是在动态语言如ActionScript中。Flex虚拟机采用了一种自动垃圾回收(Garbage Collection, ...

    Flex性能,内存管理和对象缓存

    通过本篇文章的学习,我们可以清楚地了解到对象缓存技术在提升Flex应用程序性能方面的重要作用。它不仅可以减少内存使用,还能提高应用程序的整体性能和稳定性。对于那些需要处理大量用户交互和频繁对象创建的应用来...

    Flex3.0面试题.doc

    以上是Flex3.0面试题涉及的主要知识点,包括ActionScript版本差异、开发框架特点、MVC实施、内存管理、垃圾回收机制、前后端通信、性能优化以及Flash与Flex的协作方式。这些知识对于理解和实践Flex3.0开发至关重要。

    Flex 3企业级 Web应用系统设计与实现

    1. 垃圾回收:理解ActionScript 3.0的垃圾回收机制,避免内存泄漏。 2. 性能监控:使用Flex Profiler分析应用性能,找出瓶颈并进行优化。 3. 缓存策略:有效利用Flash Player的本地存储,缓存数据以提高性能。 七、...

    IT技术文章示例

    启动参数用于控制JVM的行为,常见的参数包括-Xms(最小堆内存)、-Xmx(最大堆内存)、-XX:+UseConcMarkSweepGC(垃圾回收算法)等。 ### 26. 一个优秀的JAR包下载站点:Apache Maven Repository Apache Maven ...

    Flash优化

    3. **内存管理**:有效释放不再使用的对象,避免内存泄漏,合理使用垃圾回收机制。 4. **使用开发工具**:利用Adobe Animate的性能分析器或其他第三方工具检测性能问题。 5. **Flex 4框架**:学习Flex 4的新特性,...

    转正工作总结

    6. **利用垃圾回收机制**:及时释放不再使用的对象,防止内存泄漏。 转正工作总结则是软件工程师在试用期结束时对个人工作成绩、问题及改进方向的反思和记录。通常会包含以下内容: 1. **项目参与**:列出参与的...

    AS3高手之路

    - **性能优化**:作者还提到了BitmapData对象的内存管理问题,比如如何避免过多的垃圾回收,以确保程序运行效率。 - **Sprite 类**:Sprite 类是AS3中最常用的显示对象容器之一,它可以包含多个子项,并提供了一...

    各学习网站积累

    10. **性能优化**:学习如何避免内存泄漏,正确使用垃圾回收,以及优化代码以获得更好的运行效率。 11. **Flex框架**:如果PDF还包括Flex相关内容,那么Flex Builder、MXML和CSS布局也会是重要的学习部分。 通过...

Global site tag (gtag.js) - Google Analytics