如何使用ActionScript 3强行从内存中卸载ByteArray
?
我尝试了以下内容:
// 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;
}
答案 0 :(得分:33)
我认为你没有什么可担心的。如果System.totalMemory
出现故障,您可以放松一下。操作系统很可能不会回收新释放的内存(预计下一次Flash Player会要求更多内存)。
尝试做一些非常耗费内存的事情,我确信您会注意到分配给Flash Player的内存会减少,而是用于其他进程。
正如我所理解的那样,从查看分配给每个流程的金额,甚至分配的总金额来看,现代操作系统中的内存管理并不直观。
当我使用我的Mac 5分钟时,使用了95%的3 GB RAM,并且它将保持这种状态,它永远不会停止。这就是操作系统处理内存的方式。
只要在其他地方不需要它,即使已经退出的进程仍然分配了内存(例如,这可以使它们在下次更快启动)。
答案 1 :(得分:23)
(我对此并不乐观,但......)
AS3使用非确定性垃圾收集。这意味着只要运行时感觉它就会释放未引用的内存(除非有理由运行,否则通常不会释放,因为这是一项昂贵的执行操作)。这与大多数现代垃圾收集语言(如C#和Java)使用的方法相同。
假设没有其他对byteArray
指向的内存或数组本身内的项的引用,则在退出声明byteArray
的范围后,内存将在某个时刻释放。
你可以强制进行垃圾收集,但实际上你不应该这样做。如果你这样做,那只做测试......如果你在生产中这样做,你会比帮助它更能伤害你的表现。
要强制GC,请尝试(是,两次):
flash.system.System.gc();
flash.system.System.gc();
答案 2 :(得分:18)
看一下这篇文章
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();
}
答案 3 :(得分:14)
不幸的是,当谈到 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
的动态属性,您可以释放为其分配的内存。
答案 4 :(得分:14)
我相信你已回答了自己的问题......
System.totalMemory
为您提供“已使用”但未分配的内存总量。您的应用程序可能只使用20mb是准确的,但它有5mb可以免费用于将来的分配。
我不确定Adobe文档是否能说明它管理内存的方式......
答案 5 :(得分:10)
因此,如果我从MySQL加载20MB,在任务管理器中,应用程序的RAM增加大约25MB。然后当我关闭连接并尝试处理ByteArray时,RAM永远不会释放。但是,如果我使用System.totalMemory,则flash播放器会显示正在释放内存,但事实并非如此。
Flash应用程序是否正在执行类似Java的操作并保留堆空间并且在应用程序退出之前不会释放它?
嗯,是的,不,正如你可能从无数的博客中读到的那样,AVM2中的GC是乐观的,并将以自己神秘的方式运作。所以它确实有点像Java并尝试保留堆空间,但是如果你让它足够长并开始做其他消耗一些重要内存的操作,它将释放前一个空间。您可以使用分析器过夜,并在应用程序顶部运行一些测试。
答案 6 :(得分:9)
因此,如果我从MySQL加载20MB,在任务管理器中,应用程序的RAM增加大约25MB。然后当我关闭连接并尝试处理ByteArray时,RAM永远不会释放。但是,如果我使用System.totalMemory,则flash播放器会显示正在释放内存,但事实并非如此。
玩家正在“释放”记忆。如果您最小化窗口并恢复它,您应该看到该记忆现在更接近System.totalMemory显示的内容。
您可能还有兴趣使用FlexBuilder的分析工具,它可以向您显示您是否真的有内存泄漏。
答案 7 :(得分:7)