gpt4 book ai didi

flash - 为什么System.total内存不断增加?

转载 作者:行者123 更新时间:2023-12-04 09:08:48 29 4
gpt4 key购买 nike

我有这个空白项目,只是要签出System.totalMemory变量。据我所见,我得到以下值:

3076
3092
3096
3088
3092
3096
3100
3104
3108
3112
3117
3121
3125
3129
3133
3137
3141
3145
3149
...
And so on


我没有打开Flash,没有Internet浏览器,没有Flash的其他实例。

该项目为空白,只有一个静态文本和一个动态文本,称为“内存”。一个* .as文件,其中包含以下代码:

package{
import flash.display.Sprite;
import flash.events.Event;
import flash.system.System;
import flash.text.TextField;
public class Test extends Sprite {
public function Test() {
this.addEventListener(Event.ENTER_FRAME,Loop);
}
public function Loop(e:Event) {
memory.text = String(System.totalMemory);
}
}
}


这些是我的发布设置。




我在Debug和Published * .swf中测试,结果相同。

我对此一无所知,请帮忙。

最佳答案

我认为您有几处错误。

首先,您的跟踪显示totalMemory截断最后3位数字(因为您没有在代码中这样做,所以我认为这是由于TextField的宽度)。它的增长如下:3076、3092、3096等。这些(大约)千字节,而不是字节。然后您评论:“ 2小时后的总内存:3887104。我的天哪”。现在,如果按3,887,104 Kb表示3,887,104 Kb,则约为3.8 Gb。我怀疑情况是否如此,因此假设您的意思是3,887,104字节。大约3,800 Kb或3.8 Mb。实际上,更重要的是,与您最初的3,076 Kb的距离不远。

我认为这实际上误导了另一位发布者,使他认为播放器实际上将内存使用量增加了4,096字节(即4 Kb)增加了4个字节。

其次,即使代码非常简单,它也会占用内存。对于初学者,每次分派ENTER_FRAME事件时,都会创建一个Event对象,该对象又包含对其他对象,字符串等的引用。那需要记忆。然后,您将数字隐式转换为字符串(通过打印totalMemory)。无论是否进行显式转换,这都会占用内存(如果进行跟踪而不是使用文本字段,则同样适用)。最重要的是,可以肯定的是,从“动作脚本的观点”来看,正在进行的其他工作并不明显。

现在,我认为部分问题是您正在跟踪当前的totalMemory。看着它,似乎一直在缓慢而稳定地增长。的确是这样,但您可能会丢失的是,GC的运行速度较慢,并释放了许多正在累积的内存。

如果您修改代码以计算一些东西,这将更加明显。

package{
import flash.display.Sprite;
import flash.events.Event;
import flash.system.System;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.text.TextField;
import flash.text.TextFormat;

public class Test extends Sprite {

private var peak:int = 0;
private var prev:int = 0;
private var cur:int = 0;
private var diff:int = 0;
private var decreaseCount:int = 0;
private var increaseCount:int = 0;
private var accumIncrease:int = 0;
private var accumDecrease:int = 0;
private var maxIncrease:int = 0;
private var maxDecrease:int = 0;
private var initTime:Number = 0;
private var elapsed:Number = 0;

private var time:TextField;
private var info:TextField;

public function Test() {
initTime = getTimer();
var tf:TextFormat = new TextFormat("Courier New",12);
time = new TextField();
time.defaultTextFormat = tf;
time.width = 250;
addChild(time);
info = new TextField();
info.defaultTextFormat = tf;
info.y = 15;
info.width = 250;
info.height = 250;
addChild(info);
addEventListener(Event.ENTER_FRAME,Loop);
}

public function Loop(e:Event) {
cur = System.totalMemory >> 12;

elapsed = (getTimer() - initTime) / 1000;
time.text = "time running: " + elapsed;

if(cur == prev) {
return;
}

if(cur > peak) {
peak = cur;
}

if(cur > prev && prev > 0) {
diff = cur - prev;
if(diff > maxIncrease) {
maxIncrease = diff;
}
accumIncrease += diff;
increaseCount++;
} else if(cur < prev) {
diff = prev - cur;
if(diff > maxDecrease) {
maxDecrease = diff;
}
accumDecrease += diff;
diff = -diff;
decreaseCount++;
}

info.text = "current: " + cur + "\n"
+ "previous: " + prev + "\n"
+ "diff: " + diff + "\n"
+ "peak: " + peak + "\n"
+ "increaseCount: " + increaseCount + "\n"
+ "decreaseCount: " + decreaseCount + "\n"
+ "accumIncrease: " + accumIncrease + "\n"
+ "accumDecrease: " + accumDecrease + "\n"
+ "maxIncrease: " + maxIncrease + "\n"
+ "maxDecrease: " + maxDecrease;

prev = cur;

}
}
}


我使用4096字节的块作为单位(这就是为什么我正在做System.totalMemory >>12。这只是说System.totalMemory / 4096的一种奇特方法)。我认为它更易于管理,而且totalMemory总是返回4096 byes或4kb的倍数。您可以在此处阅读有关Flash GC的更多信息: https://developer.mozilla.org/en/MMgc。播放器的那部分是开源的,如果您愿意的话,您甚至可以阅读这些资源。

有关代码跟踪内容的简要说明:


运行时间:瑞士法郎开始运行以来经过的秒数
当前:System.totalMemory返回的内存量,以4 Kb为块
上一个:totalMemory的上一个值
diff:当前和以前的差异。可能是负面的。这将显示内存使用量相对于先前值是增加还是减少。
高峰:自我解释。这不是很重要。
增加计数:当前次数大于之前的次数。基本上,它告诉您totalMemory增加了多少次,至少1个块。
reductionCount:以前的次数大于当前的次数。这将告诉您释放了多少次内存。
accumIncrease:正差异的累加值。让您知道已经分配了多少块。
accumDecrease:负差异的累加值。让您知道已经释放了多少块。
maxIncrease:在两个循环执行中分配的最大块数。
maxDecrease:在两个循环执行中释放的最大块数。


现在,让我们看一下使用此代码拍摄的一些“快照”。

这是SWF运行3秒钟时拍摄的早期快照。请注意,当前读数为760。


运行时间:3秒
当前:760
以前的:759
差异:1
峰值:760
增加计数:3
减少计数:0
累计增加:6
减少:0
maxIncrease:3
maxDecrease:0


大约10分钟后:


运行时间:574秒
目前:763
以前的:762
curDiff:1
最高:834
增加计数:127
减少计数:3
累计增加:132
减少:123
maxIncrease:3
max减少:72


需要注意的几件事:


大约10分钟后,电流为
非常接近3秒:
763对760。这意味着现在,
totalMemory为3.052 Mb;在3
秒,它是3,040 Mb。
增加数很高,并且
减少计数低。那意味着
播放器已分配内存
很多次,但非常释放
谨慎地。
maxIncrease低且maxDecrease
高。将其添加到2)中
一个有趣的模式:玩家
分配少量的块
经常。它将它们释放
慢得多的步伐;但是,当它做的时候
释放大量的块。
accumIncrease和accumDecrease是
也很近


现在,让swf运行更多时间。运行50分钟后,快照如下所示:


运行时间:2989秒
当前:931
以前的:930
差异:1
最高:931
增加数:690
减少计数:8
累计增加:699
累计减少:522
maxIncrease:3
max减少:163


此时,您可能会认为存在泄漏。请注意,当前的内存是931,而最初的是760。

但是看看3124秒(约52分钟)会发生什么:


运行时间:3142秒
当前:767
以前的:768
差异:-1
最高:962
增加计数:720
减少计数:10
累计增加:730
累计减少:717
maxIncrease:3
最大减少:194


在GC启动之前,峰值增加到962。但是在那之后,电流再次下降到767,非常接近初始值760。

因此,总结起来,内存使用量增长的事实并不一定意味着存在泄漏。您只需要处理播放器是垃圾收集的事实,并且该过程是不确定的。最终将在某个时候回收内存(当然,除非代码中确实有泄漏)。您无法确定何时会发生这种情况。当玩家确定必要时,它将发生。一般来说,玩家知道得更多。

也就是说,我认为重要的是要注意代码中可能的泄漏。但是,仅跟踪System.totalMemory并不能帮助您确定这一点。如果可以的话,请使用诸如Flex Builder的内存分析器之类的工具,它虽然不完美,但可以为您提供更多有用的信息。并且在将侦听器添加到舞台上和使用计时器时要小心,这是Flash播放器中最大的内存泄漏元凶。

关于flash - 为什么System.total内存不断增加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1020146/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com