找回密码
 点一下
查看: 7990|回复: 26

[研究之一]关于触发器的排泄

[复制链接]
发表于 2009-6-7 19:13:40 | 显示全部楼层 |阅读模式
据老狼所说(找不到原帖了),销毁触发时要手动销毁触发条件和触发动作,对此做了测试,结论是(War3 1.23):

event:
trigger销毁后不需要排泄(jass里也无法排泄)

triggercondition:
trigger销毁后不需要排泄

triggeraction
trigger销毁后需要单独排泄

额外一点是
对同一个code反复使用Condition()/Filter()不会额外占用内存(不知道和RPBug有没有关系- -)

测试代码如下:
[trigger]
t
    事件
        时间 - 游戏开始 1.00 秒
    条件
    动作
        游戏 - 对 玩家1(红色) 在屏幕位移(0.00,0.00)处显示文本: sfd
        For循环整数A从 1 到 10000, 做动作
            Loop - 动作
                For循环整数B从 1 到 5000, 做动作
                    Loop - 动作
                        自定义代码: set udg_boolexpr=Condition(function IsUnitEnemyEx)
                        自定义代码: set udg_boolexpr=Filter(function IsUnitEnemyEx)
                        自定义代码: set udg_t=CreateTrigger()
                        自定义代码: call TriggerRegisterGameEvent(udg_t,EVENT_GAME_SAVE)
                        自定义代码: call TriggerAddCondition(udg_t,Condition(function IsUnitEnemyEx))
                        自定义代码: set udg_action=TriggerAddAction(udg_t,function FrostHellLoop)
                        自定义代码: call TriggerRemoveAction(udg_t,udg_action)
                        自定义代码: call DestroyTrigger(udg_t)
                游戏 - 对 玩家1(红色) 在屏幕位移(0.00,0.00)处显示文本: (转换 i 为字符串)
                设置 i = (i + 1)
                等待 0.01 秒
[/trigger]

去掉TriggerRemoveAction一行就会运行内存暴涨,否则内存不动
也就是说,坚持把动作写在条件里的筒子们可以放心地直接DestroyTrigger()了~

测试时发现个情况是如果整数B的循环太大可能会使触发执行完第一次B循环后直接结束(比如把5000改大),具体原因尚未查证或研究


就这些,权当抛砖引玉,另外有人能给下老狼研究的原帖么,谢~

评分

参与人数 1威望 +22 收起 理由
血戮魔动冰 + 22 …………我没见过…… 补加

查看全部评分

发表于 2009-6-7 19:24:27 | 显示全部楼层
研究之二是什么?
回复

使用道具 举报

发表于 2009-6-9 11:26:43 | 显示全部楼层
原来如此,条件中会自行排泄吗
回复

使用道具 举报

发表于 2009-6-9 13:15:41 | 显示全部楼层
"测试时发现个情况是如果整数B的循环太大可能会使触发执行完第一次B循环后直接结束(比如把5000改大),具体原因尚未查证或研究"
……每次循环后+个等待0.00秒就可以了……顺便说下……把数改小些……否则研究会被某种因素而视为无效的……

还有…………LZ最好看看一开始的创建的HandleAddress和最后创建的HandleAddress…………你会发现差了很多的……然后…………就泄露了……只不过这些泄露太小,光看内存察觉不了的……
不过鼓励一下吧………………
回复

使用道具 举报

发表于 2009-6-10 05:16:22 | 显示全部楼层
我测试了下。
楼主结论完全正确。。。原来以前做了很多无用功。。。

结论.jpg
测试的是handle变化



果整数B的循环太大可能会使触发执行完第一次B循环后直接结束(比如把5000改大),
对于这点 是触发器里动作有操作上限 循环也有上限 5000太多了。。会被魔兽杀死


ps:地下室...

触发器排泄分析.w3x

22 KB, 下载次数: 87

回复

使用道具 举报

发表于 2009-6-10 17:59:47 | 显示全部楼层
恩恩?这是真的吗?

好吧…………需要LS贴测试的结果,就是Handle表的变化的测试结果~
最好代码贴上~~
回复

使用道具 举报

发表于 2009-6-10 18:17:06 | 显示全部楼层
附件:  触发器排泄分析.w3x (22 K) 下载次数:0 [删除]


自己看把...
地图就在你头顶...
回复

使用道具 举报

 楼主| 发表于 2009-6-10 18:35:50 | 显示全部楼层
引用第3楼血戮魔动冰于2009-06-09 13:15发表的  :
"测试时发现个情况是如果整数B的循环太大可能会使触发执行完第一次B循环后直接结束(比如把5000改大),具体原因尚未查证或研究"
……每次循环后+个等待0.00秒就可以了……顺便说下……把数改小些……否则研究会被某种因素而视为无效的……

还有…………LZ最好看看一开始的创建的HandleAddress和最后创建的HandleAddress…………你会发现差了很多的……然后…………就泄露了……只不过这些泄露太小,光看内存察觉不了的……
不过鼓励一下吧………………

“被某种因素而视为无效”是什么意思?

至于HandleAddress,是不是因为handle短期内不会重复利用的问题?
因为测试的时候遇到过执行前若干k次时内存略涨,之后保持恒定的情况

确实看handle来确定理论上是否有泄漏更严格些,虽然我个人也对理论和完美更执著些,不过从实用主义的角度,如果上w次的行为也没有导致10m级的内存增加,应该是可以接受的(triggeraction会导致100m级的内存增加……)

PS问一个小问题,直接RemoveUnit()可以保证不泄漏么,我用RemoveUnit(CreateUnit())进行暴力大数内存测试的结果是没有
回复

使用道具 举报

发表于 2009-6-10 18:51:47 | 显示全部楼层
=_=地图完全被54了..
只要handle数据没有被变量记录过 那直接删除 是不会泄露的.

触发器也会占用handle 触发器执行完后就会释放
连续创建删除 也不会怎么增长的...增长到一定长度比如 多了1-2位时 会又从最低的开始..
回复

使用道具 举报

发表于 2009-6-10 21:40:21 | 显示全部楼层
引用第7楼westwood于2009-06-10 18:35发表的  :


“被某种因素而视为无效”是什么意思?

至于HandleAddress,是不是因为handle短期内不会重复利用的问题?
.......
“被某种因素而视为无效”
这个大约是等待有问题?
handle短期内不会重复利用?
这个,只要连接数减为0,也就是局域变量设为0,并且实际对象被删除
那么handle是会自动释放并可以重复利用

关于unit
它跟一般的handle有些区别
remove以后,如果链接数为0
它的handle不会在等待中释放
而是在触发运行结束后释放……
因为只是无意中发现
所以没有过多测试
所以我自己也不是十分清楚
回复

使用道具 举报

发表于 2009-6-10 22:12:18 | 显示全部楼层
引用第4楼linzefei于2009-06-10 05:16发表的  :
我测试了下。
楼主结论完全正确。。。原来以前做了很多无用功。。。

真的哎,居然这样,从来都没想到测试触发条件的排泄问题,太感谢LZ的测试了。
回复

使用道具 举报

发表于 2009-6-10 22:48:35 | 显示全部楼层
这个不是早有定论了吗,4~5楼的话还暗藏什么玄机,我看不懂
回复

使用道具 举报

发表于 2009-6-11 00:12:50 | 显示全部楼层
原来是真的也
回复

使用道具 举报

发表于 2009-6-11 04:17:23 | 显示全部楼层
引用第11楼actboy168于2009-06-10 22:48发表的  :
这个不是早有定论了吗,4~5楼的话还暗藏什么玄机,我看不懂


我也看不懂。。我只是帮楼主补充测试了下`~

楼主直接看内存。。我去看handle变化。。
回复

使用道具 举报

发表于 2009-6-11 09:13:13 | 显示全部楼层
一直都没注意,TriggerAddAction居然有一个triggeraction类型的返回值。。。

那么,实际上这个triggeraction会在每次你添加的时候都分配一些空间,但是要命的是:这个action是不能被真正删除的。。。。

实际测试中,即使你set=null这个内存也不会释放,内存占用大约为6k。

猜测这个空间被用于存放triggeraction的公用变量,比如TriggerUnit()之类的东西,而condition没有这么个空间,是寄生于trigger中的。

反正就是,TriggerAddAction会将一段代码实体化,内容大概是一个指向code的指针和一个堆栈。

所以,以后都用condition好了。

不过condition没有自己的存储空间因此不支持等待之类的。
回复

使用道具 举报

发表于 2009-6-11 09:47:56 | 显示全部楼层
但是要命的是:这个action是不能被真正删除的。。。。


?
[jass]native TriggerRemoveAction  takes trigger whichTrigger, triggeraction whichAction returns nothing//删除指定动作
native TriggerClearActions  takes trigger whichTrigger returns nothing//貌似可以删掉指定触发器的所有动作(1个触发器可以很多动作的)[/jass]

哦。。错了。。刚去测试了下    TriggerClearActions 并没有删除handle实体 所以会泄露  估计是只把 动作和触发器断开了

触发器排泄分析.w3x

22 KB, 下载次数: 24

回复

使用道具 举报

发表于 2009-6-11 10:13:06 | 显示全部楼层

路过学习下,以后就用Condition了
回复

使用道具 举报

发表于 2009-6-11 10:17:23 | 显示全部楼层
原来是不需要使用destroyboolexpr的。
回复

使用道具 举报

发表于 2009-6-11 12:03:09 | 显示全部楼层
linzefei 可以测试下TriggerClearConditions()的效果么?
因为之前的教程就是说此语句和TriggerClearActions()效果等同,那么它真的会有泄露么?删除触发之后呢?
回复

使用道具 举报

发表于 2009-6-11 12:40:13 | 显示全部楼层
如果不删触发器
TriggerClearConditions()这个有效 能防止泄露

如果删触发器 这个TriggerClearConditions() 有没有 都没差别

触发器排泄分析.w3x

23 KB, 下载次数: 39

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 18:07 , Processed in 0.267289 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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