|
发表于 2009-1-17 11:05:53
|
显示全部楼层
嗯,早上我做了下试验。下面的东西都是玩家摁Esc触发。每次间隔大概一秒。
一
[codes=jass]function aaa takes nothing returns boolean
local timer array h
local integer n=0
loop
set h[n]=CreateTimer()
call DestroyTimer(h[n])
set h[n]=null
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为
92,104(初始) 93,424 93,452 93,456 93,884 93,896 93,884 93,884 93,884 93,896
这是在排泄良好的情况下。
二
[codes=jass]globals
timer array h
endglobals
function aaa takes nothing returns boolean
local integer n=0
loop
set h[n]=CreateTimer()
call DestroyTimer(h[n])
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为
92,100(初始) 93,416 93,568 93,684 93,772 94,320 94,508 94,592 94,700 94,788 94,876 94,972
貌似这样会有泄露?它不是自己会回收内存的吗?
再一次测试
92,080(初始) 93,400 93,936 94,056 94,152 94,252 94,440 94,536 94,620 94,720 94,820 94.908
三
[codes=jass]globals
timer array h
endglobals
function aaa takes nothing returns boolean
local integer n=0
loop
set h[n]=null
set h[n]=CreateTimer()
call DestroyTimer(h[n])
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为(这个应该就和DataSystem同理了,我们先不说Handle的变化,单看内存)
92,112(初始) 93,880 93,976 94,088 94,184 94,284 94,460 94,556 94,664 94,752 94,856 94,952
四
[codes=jass]globals
timer array h
endglobals
function aaa takes nothing returns boolean
local integer n=0
loop
set h[n]=CreateTimer()
call DestroyTimer(h[n])
set h[n]=null
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为
92,104(初始) 93,432 93,448 93.872 93,964 93,864 93,864 93,864 93,864 ...
好了。以上是关于内存方面的,看试验二应该知道全局变量也要set null,而三说明什么,这样做也同样会有泄露存在。试验四排泄良好。
14:19
嗯,下午接着做了些试验。
五
[codes=jass]globals
timer array nnn
integer I
timer Tm
endglobals
function aaa takes nothing returns boolean
local integer n=0
local integer I
local timer Tm
loop
set nnn[n]=null
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set n=n+1
exitwhen n>3000
endloop
set n=GetRandomInt(0,3000)
set Tm=nnn[n]
Bug(I-n)
Bug(n)
set I=0
return false
endfunction[/codes]
这样就可以查看DataSystem分配handle的情况了,由上试验三直接修改过来的。运行后屏幕上显示1048683和随机的n,这说明下脚标的获取是正确的。不过,泄露依然在,依然在。
那接下来看看泄露是怎么产生的。
六(1)
[codes=jass]globals
timer array nnn
integer I
timer Tm
endglobals
function aaa takes nothing returns boolean
local integer n=0
loop
set nnn[n]=null
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set nnn[n]=null
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为
92,080(初始) 94,792 94,956 95,048 95,576 95,776 95,860 95,968 96,056 96,156 96,240 96,340
六(2)
[codes=jass]globals
timer array nnn
integer I
timer Tm
endglobals
function aaa takes nothing returns boolean
local integer n=0
loop
set nnn[n]=null
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为
92,136(初始) 94,836 94,972 95,096 95,224 95,428 95,960 96,056 96,144 96,244 96,340 96,436
嗯,就目前来看呢,我们用最后占用的内存减去第二个数值,然后除以10来看下平均每3000个变量会泄露多少。
试验二,(94,972-93,416)/10=155.6
(94,908-93,400)/10=150.8
试验三,(94,952-93,880)/10=107.2
试验六(1)(96,340-94,792)/10=154.8
试验六(2)(96,436-94,836)/10=160.0
其中三的结果是最小的,我又重新测了下(嗯,因为删了一些地图上的东西,初始占用内存变小了点)
(92,240-90,672)/10=156.8 (这个测试期间内存跳了下,大概多了400)
(92.148-90,864)/10=128.4
可以认为除了三,它们是相等的。
然后看,第二个数值减去初始的内存是
一,(93,424-92,104)=1,320
二,(93,416-92,100)=1,316
(93,400-92,080)=1,320
三,(93.888-92,112)=1,776(Fk,这组数可能根本就是错的)
四,(93,432-92,104)=1,328
五,哎,跟三一样的代码,可惜没测内存...
六,(94,792-92,080)/2=1,356
(94,826-92,136)/2=1,345
这个...我不知道怎么解释这一组数,哎...
那,现在我的猜想是
1,变量在指向一个已经删除了的项时,不set null会占用对应的handle。(哦,这不是猜想,这是DataSystem的基础)
2,在另外一个函数里面再set null的话,虽然handle会释放,但是依然会泄露,只是小了些(嗯,我不清楚,因为貌似三组的数据错了,但是如果只看趋势的话,它确实是泄露了)。
3,在同一个函数内,无论set null或者指向另外一个项,都会自动释放。
现在来验证下吧,预测下面的代码会造成之前两倍的泄露。嗯嗯。
六(3)
[codes=jass]globals
timer array nnn
timer array mmm
endglobals
function aaa takes nothing returns boolean
local integer n=0
loop
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set mmm[n]=CreateTimer()
call DestroyTimer(mmm[n])
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为
89,428(初始) 92,200 92,432(跳了...92,848) 93,136 93,316 93,504 93,700 93,896 94,080 94,276 94,464 94,648
(94,648-92,200)/10=244.8
(92,200-89,428)/2=1,386
而下面这个应该是没有泄露的。
六(4)
[codes=jass]globals
timer array nnn
endglobals
function aaa takes nothing returns boolean
local integer n=0
loop
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set nnn[n]=CreateTimer()
call DestroyTimer(nnn[n])
set nnn[n]=null
set n=n+1
exitwhen n>3000
endloop
return false
endfunction[/codes]
内存变化为
89,420(初始) 93,332 93,380 93,376 93,368(又跳...93,820) 93.816 93,804 93,816 93,820 93.820 93,820 93,808
我觉得应该忽略掉中间忽然增大的400K,我不清楚我那里出错了,但是应当是没泄露的。
(93,332-89,420)/3=1,304
嗯,说了这么一大堆,偏离正题太远啦。
结论就是DataSystem应当是可用的,话说amp34大大说的我没看懂...但是泄露是确确实实存在的,所以大家以后在使用数组记录东西的时候,删除它的时候就set null吧,别偷懒,要不然的话就使用整数数组来记录好了。
嗯,还有,我在10L有一个仿DataSystem的代码,虽然我还没有使用过它。但是基本上看不出泄露的问题,而且内存占用方面也没有大问题的,因为看上面的数据,3000个计时器也就是1,300K左右的内存吧。但是因为计时器不是删除的,所以它的使用面窄了,因为触发是不可以删除事件的,没办法重复利用了。
好了,就这么多。 |
|