[英]AS3 Memory Management reverse engineering
有人知道AS3如何真正处理垃圾回收吗? 我正在开发的游戏中释放内存有很多问题。
做了一个小演示:
public class MemoryTesting extends Sprite
{
static protected var list:Array = null;
public function onKeyDown(event:KeyboardEvent):void {
if( event.keyCode == 65 ){ //A key - adds memory
if( list == null ){
list = [];
for( var index:int = 0; index < 10000000; ++index ){
list.push(new Matrix3D());
}
}
}
else{ //Any other key removes memory.
if( list ){
var size:int = list.length;
for( var index:int = 0; index < size; ++index ){
list.pop();
}
list.length = 0;
list = null;
}
System.gc();
}
}
}
在Windows 7中运行Flash Player Debugger独立的11.4r402。在没有按下任何键的情况下,看着任务管理器,调试器处于11,000 K的空闲状态。
按下(添加10Mil Matrix3D类)会将其增加到962,000K。
按下另一个键(删除对矩阵的引用并使数组为空)取决于我按下它的次数。
我听到有人在谈论GC等待“最佳时机”的到来。 但是,这是一个空的应用程序,甚至不是enter_frame事件,也没有时间让您空闲以删除剩余的27,000 K(38,000-11,000)。
坐在新的低点,如果我们重新添加矩阵,我们将回升到975,000K。
也就是说,比第一次多出13,000K。 如果我重复此添加/删除操作,它将保持不变,最高可达975,000 K,最高可达38,000K。
请记住,此应用程序中没有任何操作。 我的实际应用程序具有650mb的原始位图数据,更不用说100mb的SWF解析和500mb的XML类(仅在初始化代码中使用)。
我读过很多遍,即使手动调用GC也很糟糕,更不用说6次了。 但是,如果我不发布,任何Matrix3D都不会发布。
有人怎么处理呢? 在初始化结束时,我是否只需调用GC 6次?
编辑:
我正在发布模式下测试差异,以及是否在没有System.gc()调用的情况下进行了测试,如果没有从闪存中释放内存,至少要正确地重新使用它。 它最终会实现,但具有更高的新足迹。 完整列表位于990,000 K,清除后达到1,050,000K。
这是用于最初花费我们962,000 K RAM的数据的。 那是90MB的内部闪存GC内存。 更不用说忽略它永远不会将内存还给操作系统(没有显式GC调用)。
Actionscript的GC很奇怪,没什么好说的,
如果您尝试使用类似的方法,它会有所帮助(我刚刚进行了测试,GC在第一次尝试(按键单击)时就清除了内存),只是将Array更改为Vector以更快地进行测试,所以同样会发生数组也是。 在这种情况下,我的环境是FlashCC。
package
{
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.geom.Matrix3D;
import flash.net.LocalConnection;
import flash.system.System;
import flash.utils.setTimeout;
public class MemoryTesting extends Sprite
{
var list:Vector.<Matrix3D> = null;
function MemoryTesting()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
public function onKeyDown(event:KeyboardEvent):void
{
var matrx:Matrix3D;
var index:int
if (event.keyCode == 13)
{
trace(System.totalMemory, "starting to fill...")
if (list == null)
{
list = new Vector.<Matrix3D>
for (index = 0; index < 1000000; ++index)
{
matrx = new Matrix3D();
list.push(matrx);
}
}
trace(System.totalMemory, " done...")
}
else
{
if (list)
{
trace(System.totalMemory, " preparing to delete...")
list.splice(0, list.length);
list = null;
}
//force GC to work normally, it really helps (at least in my case)
try
{
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
}
catch (e:*)
{
}
setTimeout(function()
{
trace(System.totalMemory, " deleted")
}, 50)
}
}
}
}
这个奇怪的片段在大多数情况下确实有帮助
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*) {}
这是令人讨厌的文章: http ://gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.