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

AS3内存保护(加载器/位图数据/位图/精灵)

  •  3
  • rinogo  · 技术社区  · 15 年前

    我正在努力减少AS3应用程序的内存需求。我理解,一旦对象没有剩余的引用,它就会被标记为垃圾收集的候选对象。

    是否值得尝试删除对不再使用的加载程序的引用?我的第一个想法是它不值得。

    原因如下: 我的精灵需要永久引用它们显示的位图(因为精灵在我的应用程序中总是可见的)。因此,位图不能被垃圾收集。位图依赖于BitmapData对象来获取数据,因此我们无法摆脱它们。(直到现在,一切都很简单)。

    以下是我不确定的地方: BitmapData是否引用了加载程序加载的数据?换句话说,bitmapdata本质上只是一个包装器, 参考 到loader.content,或是数据 已复制 从loader.content到bitmapdata?

    如果维护了一个引用,那么我不会通过垃圾收集装载机得到任何东西…

    思想?

    3 回复  |  直到 13 年前
        1
  •  1
  •   Community CDub    7 年前

    将AMF与第三方产品结合使用,让我相信loader类试图实例化给定内容类型的新类(在本例中,它是一个位图类实例)。您可能正在从位图实例构造新的BitmapData对象。因此,我假设加载程序实例引用位图实例,在您的示例中,代码也引用位图实例。除非您在某个时刻调用bitmapdata.clone()。

    还有几种方法可以强制GC。 Force Garbage Collection in AS3?

    您可能会发现将一些任意大的对象附加到某个对象上很有用,然后强制GC查看该对象是否正在被清理或浮动。如果您使用的是类似procmon的Windows( http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx )比任务管理器更有助于进行这种外部检查。

    当然,这是一个小小的尝试和错误,但缺少类似于VisualVM的东西。( https://visualvm.dev.java.net/ )我们在这个闪光的世界里有点搞砸了。

        2
  •  1
  •   Christian Nunciato    15 年前

    这是一个很好的问题,但据我所知,答案是否定的——位图和位图数据对象都没有对加载它们的加载程序的引用,因此您可以安全地使用它们,而不必担心它们会阻止加载程序被收集。

    但是,如果您想确定,请使用 clone() method of the BitmapData class :

    克隆()

    返回一个新的BitmapData对象, 是原始实例的克隆 与包含的 位图。

    例如:

    private function onCreationComplete():void
    {
     var urlRequest:URLRequest = new URLRequest("MyPhoto.jpg");
     var loader:Loader = new Loader();
     loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete, false, 0, true);
     loader.load(urlRequest);
    }
    
    private function loader_complete(event:Event):void
    {
     var img1:Image = new Image();
     img1.source = Bitmap(event.target.content);
     addChild(img1);
    
     var img2:Image = new Image();
     img2.source = new Bitmap(event.target.content.bitmapData.clone());
     addChild(img2);
    }
    

    在这里,img1的源代码是从加载程序返回的BitmapData对象显式转换的位图。(如果检查flexbuilder中的引用,就会发现它们是相同的。)但是img2的源是一个克隆——新的字节组、新对象、新引用。

    希望这有助于解释事情。不过,负责阻止对象被垃圾收集的更可能的罪犯通常是事件处理程序。这就是为什么我设置 useWeakReference flag (见上文)当设置我的听众时,几乎是专门设置的,除非我有充分的理由不:

    使用参考 :布尔值(默认值= 错误)确定 对侦听器的引用很强或 弱的。强引用(默认) 阻止你的听众 垃圾收集。弱引用 没有。

        3
  •  0
  •   coder    13 年前

    您可以在完整的侦听器中设置一个存储位图的变量,然后在以后销毁该对象。

    public function COMPLETEListener(e:Event){
    myBitmap = e.target.loader.content;
    }
    
    public function destroy(){
    if(myBitmap is Bitmap){
                            myBitmap.bitmapData.dispose(); 
        }
    }
    

    对我来说工作很好加载一些大图像,然后在TaskManager中看到不同之处