为什么Sytem.totalMemory不断增加? [英] Why Sytem.totalMemory keeps increasing?

查看:166
本文介绍了为什么Sytem.totalMemory不断增加?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个空白项目,只是为了检查出System.totalMemory变量。据我所看到的,我得到这个值:

I have this blank project, just to check out System.totalMemory variable. As far as I can see, i get this values:

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

我没有打开Flash,没有互联网浏览器,闪存没有其他实例。

I had no Flash open, no Internet Browser, no other instance of flash.

该项目是空白,只有一个静态文本和一个动态文本,被称为记忆。其中的 *为文件中,包含此code:

The project is blank, only one static text, and one dynamic text, called 'memory'. One *.as file, that contains this code:

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);
        }
    }
}

这些都是我的发布设置。

These are my Publish Settings.

我在调试测试,并发布* .swf文件,同样的结果。

I tested in the Debug and Published *.swf, same results.

我对这个没有头绪,所以请大家帮忙。

I have no clue on this one, so please help.

推荐答案

我觉得你有几件事情是错误的。

I think you've got a couple of things wrong.

首先,你的痕迹显示totalMemory截断最后3个数字(因为你不这样做,在code,我想这是因为文本字段宽度)。它生长是这样的:3076,3092,3096,等等,这些都是(大致)千字节,而不是字节。然后,你对此有何评论:totalMemory 2小时后:3887104.我的神。现在,如果由3887104你的意思是3887104 KB,这将是大约3.8 GB。我怀疑是这样的话,让我们假设你的意思是3887104字节。这是3800 KB或3.8 MB。没有那么多的记忆,其实,更重要的是,至今没有从最初的3076 KB。

First, your traces display totalMemory truncating the last 3 digits (since you're not doing it in the code, I assume it's because of the TextField width). It grows like this: 3076, 3092, 3096, etc. These are (roughly) Kilobytes, not bytes. Then you comment: "totalMemory after 2 hours: 3887104. My god". Now, if by 3,887,104 you mean 3,887,104 Kb, that would be about 3.8 Gb. I doubt that's the case, so let's assume you mean 3,887,104 bytes. That's about 3,800 Kb or 3.8 Mb. Not that much memory, actually, and more importantly, not so far from your initial 3,076 Kb.

我觉得这实际上是误导另一个海报觉得玩家是递增的内存使用情况的4个字节,当它由4096字节,或4 KB其实递增。

I think this actually mislead another poster to think the player was incrementing memory usage by 4 bytes, when it actually increments by 4,096 bytes, or 4 Kb.

其次,即使code是很简单的,但它占用的内存。对于初学者来说,ENTER_FRAME事件每次分派,事件对象,又包含其他对象的引用,字符串等,将被创建。这需要内存。然后,你将数字转换为字符串隐式(通过打印totalMemory)。这需要记忆,也不管你做出一个明确的转换或不(同样适用,如果你犯了一个跟踪,而不是使用文本字段)。最重要的是,有是肯定的其他的东西怎么回事,是不是从看动作点可见一斑。

Second, even though the code is very simple, it does consume memory. For starters, each time the ENTER_FRAME event is dispatched, an Event object, which in turn contains references to other objects, strings, etc, is created. That takes memory. Then you are converting a number to a string implicitly (by printing totalMemory). That takes memory, too, whether you make an explicit conversion or not (the same applies if you make a trace instead of using a text field). On top of that, there's for sure other stuff going on that is not evident from an "actionscript point of view".

现在,我认为问题的一部分是,你只是跟踪当前totalMemory。看着它,它好像它的增长,缓慢但稳步地,所有的时间。这是真的,但你可能缺少的是,以较慢的速度,并释放大量内存的GC踢已积累。

Now, I think part of the problem is that you're just tracing the current totalMemory. Looking at it, it seems as though it's growing, slowly but steadily, all the time. And that is true, but you're probably missing is that, at a slower pace, the GC kicks in and releases a lot of the memory that has been accumulating.

这是更明显,如果你修改code来计算的几件事情。

This is more evident if you modify the code to calculate a few things.

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轮空或4KB的倍数。你可以阅读更多有关Flash的GC这里: https://developer.mozilla.org/en/MMgc 。播放器的那部分是开源的,你甚至可以读到的资料,如果你是这样的倾向。

I'm using chunks of 4096 bytes as the unit (That's why I'm doing System.totalMemory >> 12. Just a fancy way to say System.totalMemory / 4096). I think it's more manageable and anyway totalMemory always return multiples of 4096 byes or 4kb. You can read more about Flash's GC here: https://developer.mozilla.org/en/MMgc. That part of the player is open source, and you can even read the sources if you're so inclined.

这是什么code痕迹简要说明:

A brief explanation on what the code traces:

  • 时间运行:距今已有SWF开始运行秒
  • 电流:的内存System.totalMemory返回的金额,在块4 KB
  • previous: totalMemory的previous值
  • 差异:之间的电流和previous的差异。可能是负的。这表明,如果你的内存使用量增加或对于previous值下降。
  • 峰:自我解释。这不是很重要的。
  • increaseCount:次电流的数量大于previous。基本上,它会告诉你的totalMemory是多少次的增加,至少有1块。
  • decreaseCount:次previous数大于当前。这会告诉你多少次内存已经被释放。
  • accumIncrease:正差异的累计值。将让你知道有多少块已被分配。
  • accumDecrease:的负面差异的累计值。将让你知道有多少块已被释放。
  • maxIncrease:二环路内执行分配块的最大数量。
  • maxDecrease:二环路内执行释放块的最大数量
  • time running: Seconds elapsed since the swf began running
  • current: The amount of memory returned by System.totalMemory, in chunks of 4 Kb
  • previous: The previous value of totalMemory
  • diff: The difference between current and previous. Could be negative. This shows you if the memory usage increased or decreased with respect to the previous value.
  • peak: Self explaining. This is not very important.
  • increaseCount: The number of times current was greater that previous. Basically, it tells you how many times the totalMemory was increased, at least 1 chunk.
  • decreaseCount: The number of times previous was greater than current. This will tell you how many times memory has been released.
  • accumIncrease: The accumulated value of positive diff's. Will let you know how many chunks have been allocated.
  • accumDecrease: The accumulated value of negative diff's. Will let you know how many chunks have been released.
  • maxIncrease: The maximum number of chunks allocated within two loop executions.
  • maxDecrease: The maximum number of chunks released within two loop executions.

现在,让我们来看看一些快照采取的。

Now, let's look at some "snapshots" taken using this code.

这是一个早期的快照,当SWF已经运行3秒拍摄。只是注意,当前读取760。

This is a early snapshot, taken when the swf's been running for 3 seconds. Just note that current reads 760.

  • 运行时间:3秒
  • 电流:760
  • previous:759
  • 差异:1
  • 峰:760
  • increaseCount:3
  • decreaseCount:0
  • accumIncrease:6
  • accumDecrease:0
  • maxIncrease:3
  • maxDecrease:0
  • time running: 3 sec
  • current: 760
  • previous: 759
  • diff: 1
  • peak: 760
  • increaseCount: 3
  • decreaseCount: 0
  • accumIncrease: 6
  • accumDecrease: 0
  • maxIncrease: 3
  • maxDecrease: 0

大约10分钟后:

  • 运行时间:574秒
  • 电流:763
  • previous:762
  • curDiff:1
  • 峰:834
  • increaseCount:127
  • decreaseCount:3
  • accumIncrease:132
  • accumDecrease:123
  • maxIncrease:3
  • maxDecrease:72
  • time running: 574 sec
  • current: 763
  • previous: 762
  • curDiff: 1
  • peak: 834
  • increaseCount: 127
  • decreaseCount: 3
  • accumIncrease: 132
  • accumDecrease: 123
  • maxIncrease: 3
  • maxDecrease: 72

这几件事情需要注意:

  1. 在大约10分钟后,电流 非常接近,这是什么在3秒: 763 VS 760。也就是说,现在, 该totalMemory为3.052 MB;在3 秒,这是3,040 MB。
  2. 的增加数为高,并且 减少计数低。这意味着 玩家已经分配的内存 很多次,但非常发布 有节制地。
  3. maxIncrease低,maxDecrease 高。添加了2个),你有 一个野趣模式:玩家 分配少量组块的 经常。它释放他们在 慢得多的速度;当它,不过,它 发布块的一个大数目。
  4. accumIncrease和accumDecrease是 非常接近了。
  1. After about 10 minutes, current is very close to what it was at 3 sec: 763 vs 760. That means right now, the totalMemory is 3.052 Mb; At 3 sec, it was 3,040 Mb.
  2. The increase count is high, and the decrease count is low. That means the player has allocated memory a lot of times but released it very sparingly.
  3. maxIncrease is low and maxDecrease is high. Add that to 2) and you have an intersting pattern: The player allocates a small number of chunks frequently. It releases them at a much slower pace; when it does, though, it releases a big number of chunks.
  4. accumIncrease and accumDecrease are very close too.

现在,让SWF运行一些时间。运行50分钟后,快照看起来是这样的:

Now, let the swf run some more time. After running for 50 minutes, the snapshot looks like this:

  • 运行时间:2989秒
  • 电流:931
  • previous:930
  • 差异:1
  • 峰:931
  • increaseCount:690
  • decreaseCount:8
  • accumIncrease:699
  • accumDecrease:522
  • maxIncrease:3
  • maxDecrease:163
  • time running: 2989 sec
  • current: 931
  • previous: 930
  • diff: 1
  • peak: 931
  • increaseCount: 690
  • decreaseCount: 8
  • accumIncrease: 699
  • accumDecrease: 522
  • maxIncrease: 3
  • maxDecrease: 163

在这一点上,你可能会认为有泄漏。请注意如何在当前内存为931,与最初的760

At this point you might think there's a leak. Note how the current memory is 931, versus the initial 760.

但看看3124秒会发生什么,到52分:

But look what happens at 3124 sec, ~52 minutes:

  • 运行时间:3142秒
  • 电流:767
  • previous:768
  • 差异:-1
  • 峰:962
  • increaseCount:720
  • decreaseCount:10
  • accumIncrease:730
  • accumDecrease:717
  • maxIncrease:3
  • maxDecrease:194
  • time running: 3142 sec
  • current: 767
  • previous: 768
  • diff: -1
  • peak: 962
  • increaseCount: 720
  • decreaseCount: 10
  • accumIncrease: 730
  • accumDecrease: 717
  • maxIncrease: 3
  • maxDecrease: 194

在由GC踢,峰值上升到962。但是在这之后,电流下降到767,再次,非常接近起始760

Before the GC kicked in, the peak grew to 962. But after that, current went down to 767, again, very close to the initial 760.

所以,把它包起来,该内存使用成长并不一定意味着有一个泄漏的事实。你只需要处理的事实,球员垃圾回收,而这个过程是不确定性的。内存将eventualy在某些时候被回收(除非你做当然,在你的code泄漏,)。你无法确定何时会发生这种情况。当玩家决定有必要就会出现这种情况。而在一般情况,玩家知道更好。

So, to wrap it up, the fact that memory usage grows up does not necessarily mean there's a leak. You just have to deal with the fact that the player is garbage collected, and that process is non deterministic. Memory will eventualy be reclaimed at some point (unless you do have a leak in your code, of course). You cannot determine when will this happen. It will happen when the player determines it's necessary. And in general, the player knows better.

不过,我想这要注意可能的泄漏在code是重要的。但是,仅仅跟踪System.totalMemory是不会帮助您确定。如果可以的话,使用的工具,如Flex Builder的内存设置,这是不完美的,但给你更多有用的信息。并增加听众的阶段,使用计时器,在闪存播放器的内存泄漏的罪魁祸首时,时一定要小心。

That said, I think it's important to pay attention to possible leaks in your code. But just tracing System.totalMemory is not going to help you determine that. If you can, use a tool such as Flex Builder's memory profiler, which is not perfect but gives you much more useful info. And be careful when adding listeners to the stage and when using timers, the biggest culprits of memory leaks in the flash player.

这篇关于为什么Sytem.totalMemory不断增加?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆