- 浏览: 26652 次
文章分类
最新评论
You probably heard, read or even learned that Flex was managing the memory automatically for you, does it mean you don't have any responsibility regarding memory management in Flex? Absolutely not! If you're surprised by my answer, keep reading to understand how memory is managed in Flex using garbage collection, what responsibilities this is putting on developers, what the classical causes of memory leaks are and what are the good practices to enhance or optimize the memory management in your applications. Let's start by clarifying how Flex manages the memory before discussing common best practices regarding memory management in Flex applications . The Flash Player is responsible for providing memory for your flex application at runtime. The memory that the Flash Player provides to Flex applications must be requested to the computer's operating system. Knowing that OS memory allocation is a slow operation, the Flash Player is using a buffering technique to avoid requesting frequent allocations. This technique consists in managing two different types of memory: the OS memory1 and the Application memory. The OS memory is requested by the Flash Player in big chunks for performance reasons and kept as a memory pool in which Flex objects can be allocated. At startup, the Flash Player initializes the Application memory pool. Then, as the application creates objects, the pool is used to provide memory for the new objects. In case the pool wouldn't have enough available memory for a new object, the Flash Player requests a new big chunk to the operating system.
When your Flex application deletes some objects, the Flash Player doesn't release the corresponding OS memory but just makes it available for any further allocation (i.e. the memory is back in the Application pool). The OS memory is released only if a complete big chunk is not used anymore by your application.
To conclude on the Flex Memory Allocation topic, it must be mentioned that in Flex, you cannot explicitly delete an object (or free a chunk of memory). Object deletion, and related memory release operation, is automatically managed by the Flash Player itself, using a particular mechanism called Garbage Collection2 . Creating objects in Flex is an explicit operation that you trigger by calling the new operator. On the other hand, deleting an object is not an explicit operation (i.e. there is no delete operator3 . It's the Flash Player itself that is responsible to check which objects are useless and delete them. This mechanism is called Garbage Collection. Basically, a useless object is an object that is not anymore referenced by another active object (i.e. orphan objects). Identification of these orphan objects is a complex task and we'll see later how you, as a developer, can help the Flash Player to make it efficient . The global Garbage Collection process can be seen as a two steps process. The first step being to identify the useless objects; and the second simply consisting in releasing the corresponding memory. As we saw when detailing Flex Memory Allocation principles , the memory retrieved when a useless object is deleted becomes available for a future allocation or, in some cases, can be released at the operating system level. The first step, usually known as "Marking objects for deletion", is implemented using the two following procedures: Reference counting is one of the simplest methods for keeping track of active references. When a strong reference to an object is created, the object reference count is incremented. When a strong reference to an object is removed, the object reference count is decremented. If the reference count of an object reaches zero, it is marked for deletion. This is simple, fast and efficient but limited since it doesn't work for circular references (cross references between orphan objects). This is why the Flash Player supports a second garbage collection procedure called Mark and Sweep. Note: References can also be Weak References . This second garbage collection procedure works in a reversed way compared to the Reference Counting since it relies on identifying objects that are still accessible somewhere in the object tree of the application. The Flash Player starts at the root node of the application, and goes through every reference on it, marking each object it finds. It then iterates through each of the marked objects, marking their children. It continues this recursively until it has traversed the entire object tree of the application, marking everything it finds. At the end of the process, if an object in memory has not been marked, it means that no active reference to the object was found. So, such objects can be marked for deletion. The second step of the Flex Garbage Collection process consists in deleting the objects that have been marked for deletion. It is key to understand that this second step is a deferred operation. This means that objects are not deleted immediately when all active references are deleted. The deletion phase may happen at some "indeterminate" time in the future (yes, I said may because there are cases in which the deletion phase will never be executed). The Flash Player uses a set of heuristics that look at RAM allocation, the size of the memory stack and different other criteria to determine when to trigger the deletion. This is very important since it means that your objects, even when not referenced anymore, may continue to live for some time. It is then key to make such objects inactive so that they do not keep consuming CPU before they really be deleted (marked for deletion objects still receive events for example; the only difference compared to normal objects is that they won't be rendered). There is no way to force garbage collection for a production application. System.gc() is available but enabled only when the application runs in debug mode. Anyway, when debugging applications, it may in some cases be useful to explicitly trigger the garbage collection. In such a case, you must know that calling System.gc() does not trigger the garbage collection in a synchronous way but queues the GC request such that it be executed on the next frame. You'll often see people calling System.gc() twice in a row and explaining that the first call is for garbage marking and the second for garbage sweeping but, to my understanding, it does not work except if you wait for the next frame to call System.gc() again. In addition to being an automatic process, there is no guarantee that all Garbage Collection steps be completed in one run. Most of the time, the Flash Player will execute the Garbage Collection in several incremental steps. The last key characteristics of the Flex Garbage Collection process is that it is triggered only when allocating . This means that memory is not released when it not used anymore, but, instead, when more memory is requested by the application. Note:Grant Skinner created a Garbage Collector Interactive Simulator that nicely illustrates these principles. Now that we discussed how memory is managed in Flex using garbage collection , let's see what developers can do to help the garbage collection process and to limit memory leaks in their applications. The first easy way to reduce memory issues is just to allocate objects only when needed. This means deferring object allocation until really necessary (in createChildren() for example). This may seem obvious but is not always done correctly since the Flex Component Life Cycle remains a mystery for some of us. The second good way of reducing memory consumption is by recycling objects. Instead of releasing an old object and creating a new one, it is more efficient trying to reuse the already allocated object by resetting its properties. This can be done on a case by case basis for limited recycling or by implementing pools of reusable objects when manipulating a big number of instances. The Flex framework implements such a pool concept for item renderers by recycling them when scrolling a List or a DataGrid instead of allocating one renderer for any item in the container. Whenever an object is released, you should ensure that it is removing all references it holds on other objects. We'll see below what should be released and how but let's first highlight that the complex part here is often determining when an object is released. What I mean is that there is no destructor available in Flex, so a given object has no direct way of knowing that it has been released. In consequence, when developing a custom component, it is not always possible to ensure that releasing it is also releasing all referenced objects. To workaround this, a very common approach is to implement (and document) a clean up interface that developers using your custom component must call when they want to release an instance of your custom component. Such an interface usually offers a single method, dispose() or destroy() , in which you implement all the necessary clean up: stop timers , remove event listeners , unload loader objects , set variable references to null , … It's then up to developers using your component to call the dispose() method just before releasing your object. Event listeners are probably the most common cause of memory leaks in Flex applications. Adding an event listener creates a reference to the object holding the handler that may prevent the garbage collection until it is removed (i.e. the dispatcher references the listener). You should always remove event listeners that are no longer needed. For events that are fired only once, remove the event listener in the handler associated to the event: For events that you must process regularly during the life of your component (such as Timers, or mouse events), clean them up in your dispose() method. Note:Listeners on child objects generally do not cause memory leaks but it is anyway a good practice to remove them explicitly. When calling addEventListener() , you can force the reference that will be created on your callback to be a weak reference (by setting the fifth parameter of addEventListener() to true). Weak references are not counted as strong references are. It means that an object that has no remaining strong reference to it but only weak references will be marked for deletion. Many of us are complaining that the weakRef parameter should have true as its default value and it's quite common considering always using weak references as a good practice; anyway, using weak references is not without potentially nasty consequences. First of all, you should never use weak reference for an anonymous handler: In this example, the only reference to the function is a weak reference, meaning that next time the garbage collection runs, the function will be removed, and so, not be called anymore. Anyway, I really consider that using anonymous functions is not recommended. Now, even when using weak references for your event listeners, you should explicitly clean them up when they are no longer needed (remember that the object removal is not predictable). Note:Weak references are also supported in the Dictionary object. To use weak references in a dictionary, just set the first parameter to true when calling the dictionary constructor. Event.ADDED_TO_STAGE is only dispatched when a Display Object is added to the Display List and all its parents are also in the Display List4 . Event.REMOVED_FROM_STAGE is dispatched when an object or any of its parents is removed from the Display List5 . These events can be used to optimize the management of event listeners. When the object is on the stage, ensure that it listens to events, when it is not, stop listening to events (except for Event.ADDED_TO_STAGE of course). I initially thought that Event.REMOVED_FROM_STAGE could be considered as a destructor but this is not the case! When an object is re-parented (moved from A to B), it will receive an Event.REMOVED_FROM_STAGE (when removed from A) followed by an Event.ADDED_TO_STAGE (when added as a child of B). Note:This may also happen when objects are part of a container supporting scrollbars. When the container is resized, scrollbars may appear or disappear. In such a case, all children of the container may be re-parented in/out an internal content pane created/deleted by the resized container. Whenever using an object based on a loader (Image , SWFLoader , …), you should always call the unloadAndStop() method to unload the content from the loader and help the garbage collection. When releasing an object, you should clean up references that it was holding in variables. Flex developers are not responsible of allocating and freeing memory since this is done by the Flex framework using a Garbage Collection mechanism. But Flex developers are anyway responsible of helping the garbage collection by carefully managing data allocation and references clean up. Managing references efficiently and identifying memory leaks is not an easy task. Fortunately, some tools are available to help us among which I strongly recommend the Flex Profiler provided with Flex Builder.
发表评论
-
程序员的现实日子
2014-01-01 21:34 366好久没有写东西了,由 ... -
代码扰乱程序员日子
2014-01-01 21:31 604叙述者:李仲 31岁 程序员 记载者:杨丁 ... -
解决IE6下的,不能显示透明PNG图片的问题
2014-01-01 21:30 938本人上网上找了很多方法,觉得此文章比较详细,所以记录下来。 ... -
js判断是否是IE浏览器的几种方法
2014-01-01 21:29 556<script> if(!+[1,])alert ... -
Js 判别对象 Undefined 和 Null
2014-01-01 21:28 722Js中判别一个目标是underfined 仍是 Null一向 ... -
如何解决oracle在linux 纯字符界面安装问题?
2013-12-31 18:26 951之前在oracle 下面用图形装了(oracle图形界面安装 ... -
JS判断一个数组中是否有重复值的三种方法
2013-12-28 14:17 0方法一: -
VB URL编码与解码 URL加密与解密
2013-12-28 14:03 1087VB URL 编码与解码,VB URL 加密与解密, ... -
php反序列unserialize的一个小特性
2013-12-27 15:26 603这几天wordpress的那个反序列漏洞比较火,具体漏洞我就不 ... -
VB 获取本机网卡的有效IP、MAC、网卡、网关等信息
2013-12-27 15:19 2826之前要做个东西,写的一段,用的是 Win32_NetworkA ... -
匹配 IP 地址和域名的正则表达式
2013-12-27 15:19 3157一个IP字串,由四段组 ... -
求两个字符串最长公共子串LCS
2012-07-06 09:52 728LCS(Longest Common Subsequenc ... -
Linux - Awk 用法
2012-07-06 09:47 7790.Awk 有三个不同的版本awk,nawk 和gawk, ... -
Android 开发文档 程序基础
2012-07-03 13:44 587service没有可视化用户界面,运行在后台,在不确定的时 ... -
flex与flash的交互
2012-07-02 13:31 536所谓flex与flash的交互,说白了就是在felx里加载 ... -
flex alert的实现
2012-07-02 13:31 620本例来自于flex完全自学手册 flex/spar ... -
flex中自定义事件--------利用元数据标签
2012-07-02 13:31 561使用 标签在 MXML 文件中插入元数据标签。元数据标签 ... -
flex 初始化时的事件测试
2012-07-02 13:31 569flex 初始化时的事 ... -
Flex的通信方式(一)――Webservice-1
2012-07-02 13:31 478flex与Webservices与简单通信 1、格 ... -
Flex + LCDS + Java 入门教程
2012-07-01 11:00 558一.引 很多 ...
相关推荐
此文档描述了Detected memory leaks内存泄漏的简单检测方法,通过调用系统函数,在debug模式下运行,可以很快定位出内存泄漏之处;注:此方法并不能适用所有Detected memory leaks情况
You will begin with a basic understanding of memory management, and why memory leaks occur in an application, moving on to autorelease pools and object creation/storage to get an idea of how memory ...
Java memory leaks Java memory leaks Java memory leaks
平常我们都会用 Instrument 的 Leaks / Allocations 或其他一些开源库进行内存泄露的排查,但是检查过程非常繁琐,而且不清晰,最主要的是Abandoned memory不会被检测出来。 Leaks 从苹果的开发者文档里可以看到,一...
Learn how to analyze CLR 4 .NET application and service crashes and freezes, navigate through memory dump space (managed and unmanaged code) and diagnose corruption, leaks, CPU spikes, blocked ...
Finding memory leaks发现内存的泄漏(6KB)
Finding memory leaks发现内存的泄漏(6KB)
本程序是一个在模拟器上定位BREW应用... It can give the call stack of memory leaks (including the locations that MALLOC/REALLOC been called, and also the locations that ISHELL_CreateInstance been called).
How catch memory leaks with very little effort (7KB)
使用__wrap_malloc查找malloc导致内存泄漏问题 memory leak 内存泄漏
The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption. Use the Memory Analyzer to analyze productive heap dumps with...
The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption. Use the Memory Analyzer to analyze productive heap dumps with ...
Review of General Memory Concepts: Java Heap, Native Memory, and Memory Leaks Investigating Java Heap Out of Memory Errors Review Garbage Collection and Object References Symptoms, Causes, and ...
Fix leaks and other problems with memory and resource management Address I/O issues associated with drives, networking, serialization, and SQLite Code graphics and UIs that don’t overwhelm limited ...
BoundsChecker automatically pinpoints static, stack and heap memory errors, and resource leaks. Unlike ordinary memory-checking tools, BoundsChecker validates the latest Windows APIs including ...
Python 内存泄漏注意事项工具pdb [链接] ( ) Heapy [链接] ( ) ObjGraph [链接] ( ) Memtop [链接] ( ) Muppy [链接] ( )赫鲁库记忆解读: 常驻内存(memory_rss):在 RAM 中保存的 dyno内存部分(兆字节)。...
该资料介绍了如何检测,避免symbian编程中的内存泄漏的方法
The boot.ini option /3GB was created for those cases where systems actually support greater than 2 GB of physical memory and an application can make use of it This capability allows memory intensive ...
用法要从该项目运行特定的codemod,您将运行以下命令: npx ember-memory-leaks-codemod <TRANSFORM> path/of/files/ or/some**/*glob.js# oryarn global add ember-memory-leaks-codemodember-memory-leaks-codemod...
本程序是一个在模拟器上定位BREW应用... It can give the call stack of memory leaks (including the locations that MALLOC/REALLOC been called, and also the locations that ISHELL_CreateInstance been called).