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

发布于 2024-08-09 23:12:04 字数 433 浏览 4 评论 0原文

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

是否值得尝试删除对不再使用的 Loader 的引用?我的第一个想法是这不值得。

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

这是我不确定发生了什么的地方: BitmapData 是否有对 Loader 加载的数据的引用?换句话说,BitmapData 本质上只是一个对 loader.content 具有引用的包装器,还是将数据从 loader.content 复制到 BitmapData?

如果维护了引用,那么我不会通过垃圾收集我的加载器得到任何东西......

有什么想法吗?

I'm working on reducing the memory requirements of my AS3 app. I understand that once there are no remaining references to an object, it is flagged as being a candidate for garbage collection.

Is it even worth it to try to remove references to Loaders that are no longer actively in use? My first thought is that it is not worth it.

Here's why:
My Sprites need perpetual references to the Bitmaps they display (since the Sprites are always visible in my app). So, the Bitmaps cannot be garbage collected. The Bitmaps rely upon BitmapData objects for their data, so we can't get rid of them. (Up until this point it's all pretty straightforward).

Here's where I'm unsure of what's going on:
Does a BitmapData have a reference to the data loaded by the Loader? In other words, is BitmapData essentially just a wrapper that has a reference to loader.content, or is the data copied from loader.content to BitmapData?

If a reference is maintained, then I don't get anything by garbage collecting my loaders...

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

〗斷ホ乔殘χμё〖 2024-08-16 23:12:04

在第三方产品中使用 AMF 使我相信 Loader 类尝试实例化给定内容类型的新类(在本例中它将是 Bitmap 类实例)。您可能正在从 Bitmap 实例构造一个新的 BitmapData 对象。由此,我假设 Loader 实例引用 Bitmap 实例,并且在您的情况下,您的代码也引用 Bitmap 实例。除非在某个时刻您调用 BitmapData.clone()。

还有几种强制 GC 的方法。 在 AS3 中强制进行垃圾收集?

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

这当然是一个尝试和错误,但缺乏像 Visual VM 这样的东西(https://visualvm.dev .java.net/)我们在 Flash 世界里有点被搞砸了。

Using AMF a bit with third party products has lead me to believe the Loader class attempts to instantiate a new class of the given content type (in this case it would be a Bitmap class instance). You are probably constructing a new BitmapData object from your Bitmap instance. From that I would assume that the Loader instance references the Bitmap instance, and in your case your code also references the Bitmap instance. Unless at some point you are calling BitmapData.clone().

There are also a couple of ways to force GC. Force Garbage Collection in AS3?

You may find it useful to attach some arbitrarily large object to something, then force the GC to see if that thing is getting cleaned up or floating around. If you are using Windows something like procmon (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) is more helpful than task manager for doing this kind of external inspection.

This of course is a bit trial and error but for lack of something like Visual VM (https://visualvm.dev.java.net/) we are kind of screwed in the Flash world.

不美如何 2024-08-16 23:12:04

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

不过,如果您想绝对确定,请使用 BitmapData类的clone()方法

克隆()

返回一个新的 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 对象显式转换的 Bitmap。 (如果你检查 FlexBuilder 中的引用,你会发现它们是相同的。)但是 img2 的源是一个克隆——新的字节串、新的对象、新的引用。

希望这有助于解释事情。然而,最有可能导致对象不被垃圾收集的罪魁祸首通常是事件处理程序。这就是为什么我设置 useWeakReference 标志< /a> (见上文)在设置我的听众时,几乎完全是排他性的,除非我有充分的理由不这样做:

useWeakReference:布尔值(默认=
false) — 确定是否
对听者的提及很强烈或
虚弱的。强引用(默认)
防止你的听众
垃圾收集。弱引用
没有。

It's a good question, but to the best of my knowledge, the answer is no -- neither Bitmap nor BitmapData objects possess references to the loaders that load them, so you can safely use them without concern for their preventing your Loaders from being collected.

If you want to make absolutely sure, though, use the clone() method of the BitmapData class:

clone()

Returns a new BitmapData object that
is a clone of the original instance
with an exact copy of the contained
bitmap.

For example:

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);
}

Here, img1's source is a Bitmap cast explicitly from the BitmapData object returned by the loader. (If you examine the references in FlexBuilder, you'll see they are identical.) But img2's source is a clone -- new bunch of bytes, new object, new reference.

Hope that helps explain things. The more likely culprits responsible for keeping objects from being garbage collected, though, are usually event handlers. That's why I set the useWeakReference flag (see above) when setting up my listeners, pretty much exclusively, unless I have good reason not to:

useWeakReference:Boolean (default =
false) — Determines whether the
reference to the listener is strong or
weak. A strong reference (the default)
prevents your listener from being
garbage-collected. A weak reference
does not.

云归处 2024-08-16 23:12:04

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

public function COMPLETEListener(e:Event){
myBitmap = e.target.loader.content;
}

public function destroy(){
if(myBitmap is Bitmap){
                        myBitmap.bitmapData.dispose(); 
    }
}

对我来说效果很好,加载一些大图像并查看任务管理器中的差异

you may set a variable in the complete listener that stores the bitmap and then destroy the object later

public function COMPLETEListener(e:Event){
myBitmap = e.target.loader.content;
}

public function destroy(){
if(myBitmap is Bitmap){
                        myBitmap.bitmapData.dispose(); 
    }
}

works fine for me load some big image and see the difference in the taskmanager

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文