96

如何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;
}
4

8 回答 8

34

我不认为你有什么可担心的。如果System.totalMemory下降,您可以放松。很可能是操作系统没有回收新释放的内存(预计下次 Flash Player 会要求更多内存)。

尝试做一些占用大量内存的事情,我相信您会注意到分配给 Flash Player 的内存将减少并用于其他进程。

据我了解,从查看分配给每个进程的数量甚至分配的总量的角度来看,现代操作系统中的内存管理并不直观。

当我使用我的 Mac 5 分钟时,我的 3 GB RAM 的 95% 被使用了,并且它将保持这种状态,它永远不会出现故障。这就是操作系统处理内存的方式。

只要在其他地方不需要它,即使已经退出的进程仍然分配给它们内存(例如,这可以使它们下次启动得更快)。

于 2008-08-14T17:05:34.857 回答
24

(我对此并不积极,但是......)

AS3 使用非确定性垃圾回收,这意味着只要运行时感觉像它,就会释放取消引用的内存(通常除非有运行的理由,否则不会释放,因为执行起来是一项昂贵的操作)。这与大多数现代垃圾收集语言(如 C# 和 Java)使用的方法相同。

假设没有其他对指向的内存byteArray或数组本身中的项目的引用,则在退出声明的范围后,内存将在某个时刻被释放byteArray

您可以强制进行垃圾收集,尽管您确实不应该这样做。如果这样做,请仅用于测试。如果你在生产中这样做,你会损害性能而不是帮助它。

要强制 GC,请尝试(是的,两次):

flash.system.System.gc();
flash.system.System.gc();

你可以在这里阅读更多

于 2008-08-01T13:08:59.487 回答
19

看看这篇文章

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();
}
于 2008-08-01T13:08:59.127 回答
15

我相信你已经回答了你自己的问题。

System.totalMemory给你正在“使用”的内存总量,而不是分配的。准确地说,您的应用程序可能只使用 20 MB,但它有 5 MB 可供将来分配。

我不确定 Adob​​e 文档是否会阐明它管理内存的方式。

于 2008-08-01T14:03:22.230 回答
15

不幸的是,当涉及到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,您可以释放为它分配的内存。

于 2008-08-01T13:14:40.007 回答
11

因此,如果我从 MySQL 加载 20MB,在任务管理器中,应用程序的 RAM 会增加约 25MB。然后,当我关闭连接并尝试处理 ByteArray 时,RAM 永远不会释放。但是,如果我使用 System.totalMemory,flash player 会显示正在释放内存,但事实并非如此。

Flash 播放器是否在执行 Java 之类的操作并保留堆空间并在应用退出之前不释放它?

好吧,是也不是,正如您可能从无数博客文章中读到的那样,AVM2 中的 GC 是乐观的,并且会以自己神秘的方式工作。所以它确实有点像 Java 并试图保留堆空间。但是,如果您让它足够长的时间并开始执行其他消耗大量内存的操作,它将释放先前的空间。您可以在一夜之间使用分析器看到这一点,并在您的应用程序上运行一些测试。

于 2008-09-17T10:09:52.217 回答
10

因此,如果我从 MySQL 加载 20MB,在任务管理器中,应用程序的 RAM 会增加约 25MB。然后,当我关闭连接并尝试处理 ByteArray 时,RAM 永远不会释放。但是,如果我使用 System.totalMemory,flash player 会显示正在释放内存,但事实并非如此。

玩家正在“释放”记忆。如果您最小化窗口并恢复它,您应该会看到内存现在更接近 System.totalMemory 显示的内容。

您可能还对使用 FlexBuilder 的分析工具感兴趣,该工具可以显示您是否确实存在内存泄漏。

于 2008-10-06T18:16:34.417 回答