找回密码
 点一下
查看: 3806|回复: 17

WAR3的内存释放,到底是怎么释放的?

[复制链接]
发表于 2009-9-5 10:44:27 | 显示全部楼层 |阅读模式
前几日看见关于triggeraction 的释放问题 遂跑去实践一下
发现 不知道是什么问题 我创建了8000个trigger  triggeraction 占用 10MB 左右内存
然后我删除这8000个trigger  triggeraction  这10MB内存没有释放
再次创建8000个trigger  triggeraction  内存依旧未变 ,如果不删除这8000个trigger  triggeraction  
再次创建8000个 内存继续涨10MB 总之就是用了的内存绝对不还回来
后来继续测试 点 单位 闪电效果 特殊效果 似乎结果都一样

测试地图,为了方便是用VJ写的 不过没用什么VJ的东西 只用了全局变量随处定义 原版WE也能打开...
不是用VJ编辑器的 请不要修改否则无法测试
TriggerTest.w3m (20 KB, 下载次数: 16)

----------------------------------------测试指令---------------------------------
-CreateTrigger 创建8000个触发器
-DestroyTrigger 删除创建的8000个触发器
-CreateLocation 创建8000个点
-RemoveLocation 删除创建的8000个点
-CreateUnit      创建100个单位
-RemoveUnit   删除创建的100个单位
-CreateLightning 创建1000个闪电效果
-DestroyLightning 删除创建的1000个闪电效果
-CreateEffect       创建1000个魔法效果
-DestroyEffect     删除创建的1000个魔法效果
发表于 2009-9-5 12:29:56 | 显示全部楼层
很奇怪啊………………
应该是LZ测试出了问题。
最好把代码发上来。
回复

使用道具 举报

 楼主| 发表于 2009-9-5 12:37:47 | 显示全部楼层
Init
[codes=Jass]
globals
    trigger array triggers
    triggeraction array actions
    location array locations
    unit array units
    lightning array lightnings
    effect array effects
    integer index = 0
endglobals

//==========================================================================
function InitTrig_Init takes nothing returns nothing
endfunction
[/codes]

CreateTrigger
[codes=Jass]
function CreateTriggerTest takes nothing returns nothing
    if ( index < 8000 ) then
        set triggers[index] = CreateTrigger()
        set actions[index] = TriggerAddAction(triggers[index],function CreateTriggerTest)
        set index = index + 1
    else
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
    endif
endfunction

function Trig_CreateTrigger_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    set index = 0
    call TimerStart(t,0,true,function CreateTriggerTest)
    call BJDebugMsg("CreateTrigger")
endfunction

//==========================================================================
function InitTrig_CreateTrigger takes nothing returns nothing
    set gg_trg_CreateTrigger = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_CreateTrigger, Player(0), "-CreateTrigger", true )
    call TriggerAddAction( gg_trg_CreateTrigger, function Trig_CreateTrigger_Actions )
endfunction
[/codes]

[codes=Jass]
function DestroyTriggerTest takes nothing returns nothing
    if ( index < 8000 ) then
        call TriggerRemoveAction(triggers[index],actions[index])
        set actions[index] = null
        call DestroyTrigger(triggers[index])
        set triggers[index] = null
        set index = index + 1
    else
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
    endif
endfunction

function Trig_DestroyTrigger_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    set index = 0
    call TimerStart(t,0,true,function DestroyTriggerTest)
    call BJDebugMsg("DestroyTrigger")
endfunction

//==========================================================================
function InitTrig_DestroyTrigger takes nothing returns nothing
    set gg_trg_DestroyTrigger = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_DestroyTrigger, Player(0), "-DestroyTrigger", true )
    call TriggerAddAction( gg_trg_DestroyTrigger, function Trig_DestroyTrigger_Actions )
endfunction
[/codes]

其他的类推
回复

使用道具 举报

发表于 2009-9-5 12:41:03 | 显示全部楼层
嗯…………从代码上看不出任何问题…………
我去测试一下。
回复

使用道具 举报

发表于 2009-9-5 12:51:15 | 显示全部楼层
居然是真的………………
war3基础使用内存:
128,000+-KB。
输入:-CreateTrigger
使用内存:
138,000+-KB。
输入:-DestroyTrigger
使用内存:
138,000+-KB。和上面的结果貌似完全一样。
输入:
-CreateTrigger
-CreateTrigger
(连续两次create)
使用内存:
148,000+-KB…………
-DestroyTrigger
使用内存:
148,000+-KB………………
回复

使用道具 举报

 楼主| 发表于 2009-9-5 12:59:54 | 显示全部楼层
但是我看各种关于回收的帖子说数据销毁后内存都会下降
昨天晚上和今天早上都测试了好久还是这样 所以很郁闷的跑上来问 期待有个说明
回复

使用道具 举报

发表于 2009-9-5 13:36:16 | 显示全部楼层
嗯…………难道魔兽是申请新的内存然后就算是不用也直到游戏结束最后才释放?
不太可能啊…………
难道是全局变量数组(其实是个table)开启新元素用的?
可是如果是这样。连续两次createtrigger又怎么解释呢?
用的都是0-7999的index……
如果trigger是这样创建后即不释放等待重新使用……
那么location、unit、lightning和effect呢?

可恶………………怎么想都解释不通啊……………………
还是说测试环境出了问题?
可恶可恶………………
不过………………8000Trigger才10MB……这个…………
基本用不完吧………………
回复

使用道具 举报

 楼主| 发表于 2009-9-5 14:12:02 | 显示全部楼层
虽然用不完......... 那以后人家问我们数据回收 我们就回答不用回收 反正内存用不完..
回复

使用道具 举报

发表于 2009-9-5 14:50:18 | 显示全部楼层
…………仔细想想就算是这样也必须要回收。
回复

使用道具 举报

发表于 2009-9-5 17:28:56 | 显示全部楼层
LZ你是vista系统吗?
据橙子说:
vista 有个什么内存预分配机制- -
好像是说 先分配好 1个计算出需要的最大内存  
你去测试删除点什么的。。也会发现测试不出变化。。
记得以前都试过- -
单位组新建几万个 也没变化。。。

真郁闷啊………………
回复

使用道具 举报

 楼主| 发表于 2009-9-6 10:06:59 | 显示全部楼层
额 测试了一下 去掉了创建tiggeraction的创建 以及local 的timer以后
测试结果如下
Result.jpg

由于内存没有释放 所以推测暴雪只是断开触发器与事件和条件以及动作的一切关系,被标记未被使用状态. 并以栈的形式丢进了触发器池.取出来的时候内存地址就变成了倒序
回复

使用道具 举报

发表于 2009-9-6 11:10:21 | 显示全部楼层
triggerAction是不能被释放的

魔兽并不是释放机制,而是内存重用机制,就是说,你可以使用一个没有被占用的位置。已经被占用的位置是不会被自动释放的。
回复

使用道具 举报

发表于 2009-9-6 16:25:54 | 显示全部楼层
引用第10楼hunluan89于2009-09-06 10:06发表的  :
额 测试了一下 去掉了创建tiggeraction的创建 以及local 的timer以后
测试结果如下


由于内存没有释放 所以推测暴雪只是断开触发器与事件和条件以及动作的一切关系,被标记未被使用状态. 并以栈的形式丢进了触发器池.取出来的时候内存地址就变成了倒序

!!!严重怀疑你测的是Handle值………………
Handle值绝对不等于内存值………………
回复

使用道具 举报

发表于 2009-9-10 18:13:31 | 显示全部楼层
1]handle值和内存地址完全是不同的。

2]就像eff说的那样,war3基本上用的是内存复用机制,handle表也用的是表位复用机制。并不是说删除了单位后war3的内存占用减少了,而是你删除单位后再创建新单位的时候不会再无谓地增加内存而已。



你们也别觉得销毁对象的动作没用。创建1000个单位然后一次性删除,跟每创建一个单位然后删除,重复1000次,结果是完全不一样的。后者理想状况下只会增一个单位的内存(当然实际肯定会更多)。

否则GA何必这么多年来推行“随时注意内存泄露”的JASS编程风格。销毁对象的目的是“防止内存泄露”,而不是“减少war3当前的内存占用”。请注意两者区别。
回复

使用道具 举报

发表于 2009-9-10 18:13:54 | 显示全部楼层
同样投影之
回复

使用道具 举报

发表于 2009-9-10 18:29:35 | 显示全部楼层
另外提一点。

内存泄露造成的“卡”现象,并不仅仅是所谓的“war3内存占用过多”而导致的。

另一个原因是,handle表本身积累得过于庞大,大大影响了jass通过handle表搜索到对象的时间。因此set null排除的那区区一个表位的内存泄露,也是非常重要的。
回复

使用道具 举报

发表于 2010-1-11 16:00:17 | 显示全部楼层
引用第15楼Renee于2009-09-10 18:29发表的  :
另外提一点。

内存泄露造成的“卡”现象,并不仅仅是所谓的“war3内存占用过多”而导致的。

另一个原因是,handle表本身积累得过于庞大,大大影响了jass通过handle表搜索到对象的时间。因此set null排除的那区区一个表位的内存泄露,也是非常重要的。
那不是要五分钟垃圾回收一次
回复

使用道具 举报

发表于 2010-1-12 07:58:48 | 显示全部楼层
学习了……………………



引用第16楼rook47于2010-01-11 16:00发表的  :

那不是要五分钟垃圾回收一次
五分钟后有可能找不到一次性垃圾。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-3 07:06 , Processed in 0.211876 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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