如何ByteArray
使用 ActionScript 3 从内存中强制卸载?
我尝试了以下方法:
// First non-working solution
byteArray.length = 0;
byteArray = new ByteArray();
// Second non-working solution
for ( var i:int=0; i < byteArray.length; i++ ) {
byteArray[i] = null;
}
如何ByteArray
使用 ActionScript 3 从内存中强制卸载?
我尝试了以下方法:
// First non-working solution
byteArray.length = 0;
byteArray = new ByteArray();
// Second non-working solution
for ( var i:int=0; i < byteArray.length; i++ ) {
byteArray[i] = null;
}
我不认为你有什么可担心的。如果System.totalMemory
下降,您可以放松。很可能是操作系统没有回收新释放的内存(预计下次 Flash Player 会要求更多内存)。
尝试做一些占用大量内存的事情,我相信您会注意到分配给 Flash Player 的内存将减少并用于其他进程。
据我了解,从查看分配给每个进程的数量甚至分配的总量的角度来看,现代操作系统中的内存管理并不直观。
当我使用我的 Mac 5 分钟时,我的 3 GB RAM 的 95% 被使用了,并且它将保持这种状态,它永远不会出现故障。这就是操作系统处理内存的方式。
只要在其他地方不需要它,即使已经退出的进程仍然分配给它们内存(例如,这可以使它们下次启动得更快)。
(我对此并不积极,但是......)
AS3 使用非确定性垃圾回收,这意味着只要运行时感觉像它,就会释放取消引用的内存(通常除非有运行的理由,否则不会释放,因为执行起来是一项昂贵的操作)。这与大多数现代垃圾收集语言(如 C# 和 Java)使用的方法相同。
假设没有其他对指向的内存byteArray
或数组本身中的项目的引用,则在退出声明的范围后,内存将在某个时刻被释放byteArray
。
您可以强制进行垃圾收集,尽管您确实不应该这样做。如果这样做,请仅用于测试。如果你在生产中这样做,你会损害性能而不是帮助它。
要强制 GC,请尝试(是的,两次):
flash.system.System.gc();
flash.system.System.gc();
看看这篇文章
http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html
IANA actionscript 程序员,但是我得到的感觉是,因为垃圾收集器可能不会在您想要的时候运行。
因此 http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/
所以我建议尝试他们的收藏代码,看看是否有帮助
private var gcCount:int;
private function startGCCycle():void{
gcCount = 0;
addEventListener(Event.ENTER_FRAME, doGC);
}
private function doGC(evt:Event):void{
flash.system.System.gc();
if(++gcCount > 1){
removeEventListener(Event.ENTER_FRAME, doGC);
setTimeout(lastGC, 40);
}
}
private function lastGC():void{
flash.system.System.gc();
}
我相信你已经回答了你自己的问题。
System.totalMemory
给你正在“使用”的内存总量,而不是分配的。准确地说,您的应用程序可能只使用 20 MB,但它有 5 MB 可供将来分配。
我不确定 Adobe 文档是否会阐明它管理内存的方式。
不幸的是,当涉及到Flash/actionscript中的内存管理时,您无能为力。ActionScript 被设计为易于使用(因此他们不希望人们担心内存管理)
以下是一种解决方法,而不是创建ByteArray
变量试试这个。
var byteObject:Object = new Object();
byteObject.byteArray = new ByteArray();
...
//Then when you are finished delete the variable from byteObject
delete byteObject.byteArray;
byteArray
的动态属性在哪里byteObject
,您可以释放为它分配的内存。
因此,如果我从 MySQL 加载 20MB,在任务管理器中,应用程序的 RAM 会增加约 25MB。然后,当我关闭连接并尝试处理 ByteArray 时,RAM 永远不会释放。但是,如果我使用 System.totalMemory,flash player 会显示正在释放内存,但事实并非如此。
Flash 播放器是否在执行 Java 之类的操作并保留堆空间并在应用退出之前不释放它?
好吧,是也不是,正如您可能从无数博客文章中读到的那样,AVM2 中的 GC 是乐观的,并且会以自己神秘的方式工作。所以它确实有点像 Java 并试图保留堆空间。但是,如果您让它足够长的时间并开始执行其他消耗大量内存的操作,它将释放先前的空间。您可以在一夜之间使用分析器看到这一点,并在您的应用程序上运行一些测试。
因此,如果我从 MySQL 加载 20MB,在任务管理器中,应用程序的 RAM 会增加约 25MB。然后,当我关闭连接并尝试处理 ByteArray 时,RAM 永远不会释放。但是,如果我使用 System.totalMemory,flash player 会显示正在释放内存,但事实并非如此。
玩家正在“释放”记忆。如果您最小化窗口并恢复它,您应该会看到内存现在更接近 System.totalMemory 显示的内容。
您可能还对使用 FlexBuilder 的分析工具感兴趣,该工具可以显示您是否确实存在内存泄漏。