代码之家  ›  专栏  ›  技术社区  ›  ggambetta

闪存/flex/as3中的内存使用情况

  •  1
  • ggambetta  · 技术社区  · 14 年前

    我在闪存应用程序内存管理方面遇到了一些问题。内存使用量增长了不少,我已经跟踪到了加载资产的方式。

    我在嵌入的类中嵌入了几个光栅图像,就像这样

    [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(),执行双重本地连接技巧,或者对BitmapData对象调用Dispose()。

    当然,这是非常不受欢迎的——内存使用量将不断增长,直到SWF中的所有内容都被实例化,而不管我是否在很久以前停止使用某些资产。

    我的分析正确吗?有什么办法可以解决这个问题吗?

    4 回复  |  直到 14 年前
        1
  •  1
  •   Sophistifunk    14 年前

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

    此外,由于您使用的是嵌入的而不是加载的资产,因此实际数据可能永远不会被释放。因为它是你的SWF的一部分,我想你可以合理地期望它在你的SWF的一生中都在记忆中。

        2
  •  0
  •   Adrian Pirvulescu    14 年前

    你为什么要用这个????

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

    有时动态资源分配有问题,无法释放。我以前对flash播放器和flex也有类似的问题,比如加载和卸载同一个外部swf…内存随着加载的SWF的大小不断增加,即使在卸载SWF之后调用System.gc();也不会下降。

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


    更新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>
    

        3
  •  0
  •   Kylotan    14 年前

    此时,内存使用率上升, 这是完全正常的。然而, 取消所有对 对象无法释放内存。

    这也是完全正常的。对于任何系统来说,很少有系统能够保证停止引用代码中的对象的那一刻与将其内存返回到操作系统的那一刻相同。这就是为什么有System.gc()这样的方法,允许您在需要时强制进行清理。通常,应用程序可以实现某种类型的池,以保持对象和内存的有效性(因为内存分配通常很慢)。即使应用程序确实将内存返回到操作系统,操作系统可能仍会将其视为分配给应用程序一段时间,以防应用程序稍后需要请求更多内存。

    如果释放的内存不能被重用,您只需要担心。例如,您应该发现,如果您创建一个对象,释放它,然后重复这个过程,内存使用量不应该随着创建的对象的数量线性增长,因为以前释放的对象的内存会重新分配到新对象中。如果你能确认没有发生这种情况,编辑你的问题,这样说。:)

        4
  •  0
  •   ggambetta    14 年前

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

    更准确地说,加载一个SWF,实例化其中定义的许多类,将它们添加到显示列表中,操纵它们,然后删除所有引用并卸载SWF,这让我拥有了几乎与我开始时完全相同的内存。

    推荐文章