Flash / Flex / AS3中的内存使用情况

时间:2010-06-01 20:38:55

标签: flex flash memory-management memory-leaks actionscript-3

我在Flash应用程序中遇到内存管理问题。内存使用量增长了很多,我已经跟踪了我加载资产的方式。

我在嵌入式类中嵌入了几个光栅图像,比如

[Embed(source="/home/gabriel/text_hard.jpg")]
public static var ASSET_text_hard_DOT_jpg : Class;

然后我以这种方式实例化资产

var pClass : Class = Embedded[sResource] as Class;
return new pClass() as Bitmap;

此时,内存使用率上升,这是完全正常的。但是,null对象的所有引用都不会释放内存。

基于这种行为,看起来flash播放器在我第一次请求它时创建了一个类的实例,但从来没有发布它 - 不是没有引用,调用System.gc(),执行双重LocalConnection技巧,或者在BitmapData对象上调用dispose()。

当然,这是非常不受欢迎的 - 在SWF中的所有内容都被实例化之前,内存使用量会增加,无论我是否在很久以前停止使用某些资产。

我的分析是否正确?可以做些什么来解决这个问题吗?

4 个答案:

答案 0 :(得分:1)

确保在非调试播放器中再次运行测试。在释放资产时,调试播放器并不总是正确地回收所有内存。

此外,由于您使用的是Embedded而不是已加载的资产,因此可能无法释放实际数据。因为它是你的SWF的一部分,我会说你可以合理地期望它在你的SWF的整个生命周期中记忆。

答案 1 :(得分:0)

你为什么要用这个?

var pClass : Class = Embedded[sResource] as Class; 
return new pClass() as Bitmap;

有时动态资源分配是错误的,无法释放。我以前在使用flash player和flex时遇到过类似的问题。加载和卸载相同的外部swf ...即使我正在调用system.gc(),内存也随着加载的swf的大小不断增加而不会下降。卸下swf后。

所以我的建议是跳过这种方法并使用你所描述的第一个案例。


更新1

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx           = "http://ns.adobe.com/mxml/2009" 
    xmlns:s         = "library://ns.adobe.com/flex/spark" 
    xmlns:mx           = "library://ns.adobe.com/flex/mx" 
    creationComplete   = "creationComplete()">

<fx:Script>
    <![CDATA[



        [Embed(source="/assets/logo1w.png")]
        private static var asset1:Class;

        [Embed(source="/assets/060110sinkhole.jpg")]
        private static var asset2:Class; 


        private static var _dict:Dictionary = new Dictionary();

        private static function initDictionary():void
        {
            _dict["/assets/logo1w.png"] = asset1;
            _dict["/assets/060110sinkhole.jpg"] = asset2;
        }

        public static function getAssetClass(assetPath:String):Class
        {
            // if the asset is already in the dictionary then just return it
            if(_dict[assetPath] !=  null)
            {
                return _dict[assetPath] as Class; 
            }

            return null;
        }

        private function creationComplete():void
        {
            initDictionary();
            var asset1:Class = getAssetClass("/assets/logo1w.png");
            var asset2:Class = getAssetClass("/assets/060110sinkhole.jpg");
            var asset3:Class = getAssetClass("/assets/logo1w.png");
            var asset4:Class = getAssetClass("/assets/060110sinkhole.jpg");
            var asset5:Class = getAssetClass("/assets/logo1w.png");
        }
    ]]>
</fx:Script>

答案 2 :(得分:0)

  

此时,内存使用率上升,   这是完全正常的。然而,   将所有引用归零   对象不释放内存。

这也很正常。任何系统都很少能够保证在代码中停止引用对象的那一刻与其内存返回操作系统的那一刻相同。这就是为什么System.gc()这样的方法存在的原因,允许你在需要时强制清理。通常,应用程序可以实现某种池化以保持对象和内存的效率(因为内存分配通常很慢)。即使应用程序确实将内存返回给操作系统,操作系统仍可能将其视为已分配给应用程序一段时间,以防应用程序需要在不久后再请求更多内容。

您只需担心释放的内存是否未被重用。例如,您应该发现,如果您创建一个对象,释放它并重复此过程,则内存使用量不应随您创建的对象数量线性增长,因为以前释放的对象的内存将重新分配到新对象中。如果您可以确认没有发生这种情况,请编辑您的问题。 :)

答案 3 :(得分:0)

事实证明我保留了对未卸载的对象的引用。非常棘手的。 GC在我描述的所有情况下都能正常工作,我怀疑这些情况可能有所不同。

更准确地说,加载一个SWF,实例化其中定义的许多类,将它们添加到显示列表,操作它们,然后删除所有引用并卸载SWF,这给我留下了几乎完全相同的内存。 / p>