找回密码
 点一下
查看: 3139|回复: 6

Handle表回收原理

[复制链接]
发表于 2009-5-26 13:09:00 | 显示全部楼层 |阅读模式
自从写了新的TimerDataSystem以后,发现Handle表回收原理貌似比较有趣~~
于是研究了一下,发现还真是蛮好玩的~~
一开始的触发如下:
[jass]
function Trig________________u_Actions takes nothing returns nothing
    local location loc = null
    local timer t = null
    local unit u = null
    local integer i = 0
    //local location array Set
    loop
        exitwhen i >= 5
        set loc = Location( 0, i )
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( loc ) ) )
        call RemoveLocation( loc )
        set loc = null
        set i = i + 1
    endloop
    call TriggerSleepAction( 2.0 )
    set i = 0
    loop
        exitwhen i >= 5
        set t = CreateTimer()
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( t ) ) )
        call DestroyTimer( t )
        set t = null
        set i = i + 1
    endloop
    call TriggerSleepAction( 2.0 )
    set i = 0
    loop
        exitwhen i >= 5
        set u = CreateUnit( Player(0), ‘hfoo’, 0, i * 30, 360 )
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( u ) ) )
        call RemoveUnit( u )
        set u = null
        set i = i + 1
    endloop
    //set i = 0
    //loop
    //    exitwhen i >= 5
    //    call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( Set ) ) )
    //    call RemoveLocation( Set )
    //    set Set = null
    //    call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, Deleted )
    //    set i = i + 1        
    //endloop
    call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, Finish )
endfunction
//===========================================================================
function InitTrig________________u takes nothing returns nothing
    set gg_trg________________u = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg________________u, 0.0 )
    call TriggerAddAction( gg_trg________________u, function Trig________________u_Actions )
endfunction
[/jass]
代码大意:
创建5个location,输出它的handleAddress,删除它。
等待2秒(【等待】或【触发、函数结束】之后,Handle表才开始清空)
创建5个timer,输出它的handleAddress,删除它。
等待2秒
创建5个unit,输出它的handleAddress,删除它。
等待2秒

屏幕的输出:
1048669
1048670
1048671
1048672
1048673
1048673
1048672
1048671
1048670
1048669
1048669
1048670
1048671
1048672
1048673
Finish

这样,很快就证明了Handle表回收原理就是按照struct来的。
——使用栈来存储空的HandleAddress,如果栈为空,那么分配新的HandleAddress(新的HandleAddress严格按照递分配增)
然后,听说lightning貌似有特异功能,于是换成了这个:
[jass]
    loop
        exitwhen i >= 5
        set l = AddLightning( CLPB, true, 0.0, 0.0, 0.0, i * 50 )
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( l ) ) )
        call DestroyLightning( l )
        set l = null
        set i = i + 1
    endloop
    call TriggerSleepAction( 2.0 )
    set i = 0
    loop
        exitwhen i >= 5
        set l = AddLightning( CLPB, true, 0.0, 0.0, 0.0, i * 50 )
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( l ) ) )
        call DestroyLightning( l )
        set l = null
        set i = i + 1
    endloop
    call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, Finish )
[/jass]
输出非常可怕!:
1
1
1
1
1
1
1
1
1
1
Finish
将第一个循环中的call DestroyLightning( l )注释掉。
输出:
1
2
3
4
5
6
6
6
6
6
Finish
我不得不惊讶了……
难道DestroyLightning()有特殊功能?
在函数、等待和触发结束之外,还可以让Handle表直接回收空的Handle?
毕竟在运行DestroyLightning()之后才有的set l = null啊~
又或者说,指向lightning的变量(或者说lightning变身,其实都一样),是不计算变量连接数的吗?
注:
变量连接数——
代表有多少个变量指向一个Handle。
比如:
set u1 = <one>
set u2 = <one>
那么<one>的变量连接数就是2。
在函数、等待和触发结束之后,被执行删除操作的handle会检查变量连接数是否为0,为0则将这个Handle的HandleAddress放入Handle空位表(即栈)中,不为0则不对Handle分配的HandleAddress不做任何操作,无法再次利用,也就是说,泄露了。
而函数、触发和等待并没有自动在执行后将指向被删除的Handle的变量清0的功能……所以说,要在return,endfunction,call TriggerSleepAction()……之前放上个set XXXXX = null
注意!!
以前只说return和endfunction之前清空变量,现在在等待之前也要清空handle变量。

于是实验:
1.让Handle表直接回收空的Handle?
在第一个循环前面增加:
[jass]
    set i = 0
    loop
        exitwhen i >= 5
        set l = AddLightning( CLPB, true, 0.0, 0.0, 0.0, i * 50 )
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( l ) ) )
        set t = CreateTimer()
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( t ) ) )
        call DestroyTimer( t )
        set t = null
        call DestroyLightning( l )
        set l = null
        set i = i + 1
    endloop
[/jass]
输出:
1
1048671
1
1048672
1
1048673
1
1048674
1
1048675
1
1
1
1
1
1
1
1
1
1
Finish
看来DestroyLightning()是没有特殊功能了…………
2.将第一个循环的set l = null注释掉…………
输出:
1
1
1
1
1
1
1
1
1
1
Finish
………………天哪…………
lightning居然真的不计算变量连接数……
不对,再换一个形式测试:
[jass]
    local lightning l = null
    local integer i = 0
    local lightning array ls
    set i = 0
    loop
        exitwhen i >= 5
        set l = AddLightning( CLPB, true, 0.0, 0.0, 0.0, i * 50 )
        set ls = l
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( l ) ) )
        call DestroyLightning( l )
        //set l = null
        set i = i + 1
    endloop
    call TriggerSleepAction( 2.0 )
    set i = 0
    loop
        exitwhen i >= 5
        set l = AddLightning( CLPB, true, 0.0, 0.0, 0.0, i * 50 )
        call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, I2S( H2I( l ) ) )
        call DestroyLightning( l )
        set l = null
        set i = i + 1
    endloop
    call DisplayTextToPlayer( Player( 0 ), 0.0, 0.0, Finish )
[/jass]
输出:
1
1
1
1
1
1
1
1
1
1
Finish
于是囧了…………看来lightning很可能是用于测试Handle表能否正常运行的测试产物…………
估计失败了(*^__^*) 嘻嘻……
就这样~~
Finish~~
发表于 2009-5-26 13:46:11 | 显示全部楼层
所以我说lighting是个很特殊的玩意儿
回复

使用道具 举报

 楼主| 发表于 2009-5-26 16:31:51 | 显示全部楼层
那当然~~都忘了在哪里看到的资料说lightning很特别呢…………
回复

使用道具 举报

发表于 2009-5-26 17:03:31 | 显示全部楼层
闪电特效和漂浮文字都是特别的
闪电特效是从1-200
漂浮文字是200-1
大约是如此
漂浮文字和闪电特效是无法影响到handle表的
因为不在一个表
彼此之间无法影响
回复

使用道具 举报

发表于 2009-5-27 01:15:18 | 显示全部楼层
闪电特效和漂浮文字都是特别的
闪电特效是从1-200
漂浮文字是200-1
大约是如此
漂浮文字和闪电特效是无法影响到handle表的
因为不在一个表
彼此之间无法影响


...闪电是1-无限(至少几万内是不会到的..)
漂浮是从99到1...
天气似乎从0开始 到几就不知道了.

这3个都独立
也不影响同步
回复

使用道具 举报

 楼主| 发表于 2009-5-27 12:42:03 | 显示全部楼层
诶…………
不知道texttag和天气也都是特别的呢~~~嘻嘻~~
回复

使用道具 举报

发表于 2009-5-31 07:13:39 | 显示全部楼层
引用第4楼linzefei于2009-05-27 01:15发表的  :



...闪电是1-无限(至少几万内是不会到的..)
漂浮是从99到1...
.......
独立是因为不在同一个表内吧
就像同样handle值的handle和string
两个根本不相关
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-4-26 23:30 , Processed in 0.046820 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表