找回密码
 点一下
查看: 3306|回复: 23

【有疑惑的朋友都来看看,已解决】在StoreXXXX中使用string的"+"会导致内存泄露吗?

[复制链接]
发表于 2008-8-4 12:27:23 | 显示全部楼层 |阅读模式
如题。
我的解决方案(脑中):
[codes=jass]
…………
local string s=“A”+“B”
call StoreInteger(udg_GC,I2S(H2I(GetTriggerUnit())),s,0)
set s=null
…………
[/codes]

是不是这样?

套用actboy168的回帖就是:

目前的结论是:
1 任何新出现的字符串都会记录到内存里,不能被删除,也不会删除
2 如果你的字符串达到100万条,你的地图会变卡

也就是说,除非不用string,否则一定有“泄露”(这个其实不是泄露),如果你的地图里的字符串达到或者接近100万条,那么你得考虑这个字符串的问题




泄露的定义

如果某一段内存不能被外部访问,那么这段内存就是泄露了,可以说在这个进程的生命周期里,这段内存就白白浪费了,一般泄露是不会造成系统速度变慢的,只是浪费了内存空间。


而war3里的handle泄露会变慢的原因,不是因为泄露,而是war3每次新建一个handle值时都要搜索handle表(估计是这个算法太差了),当handle表很大时,每新建一个handle值都会很慢,如果某一个点用完后,没删取,那么它还是会在handle表里,当你有很多没删除的点时,handle表就会很大,速度就变得很慢了。这也是删除后必须set null的原因。

谢谢actboy168。
非常感谢。
 楼主| 发表于 2008-8-4 12:33:42 | 显示全部楼层
(被自己忍无可忍的和谐掉了)
回复

使用道具 举报

发表于 2008-8-4 12:36:27 | 显示全部楼层
string不会泄露,就是这样
回复

使用道具 举报

 楼主| 发表于 2008-8-4 12:38:33 | 显示全部楼层
(被自己忍无可忍的和谐掉了)
回复

使用道具 举报

发表于 2008-8-4 13:06:04 | 显示全部楼层
你这样做没有意义,没办法避免
只要是连接字符串都不太好
回复

使用道具 举报

 楼主| 发表于 2008-8-4 13:14:30 | 显示全部楼层
(被自己忍无可忍的和谐掉了)
回复

使用道具 举报

发表于 2008-8-4 13:16:11 | 显示全部楼层
目前的结论是:
1 任何新出现的字符串都会记录到内存里,不能被删除,也不会删除
2 如果你的字符串达到100万条,你的地图会变卡

也就是说,除非不用string,否则一定有“泄露”(这个其实不是泄露),如果你的地图里的字符串达到或者接近100万条,那么你得考虑这个字符串的问题




泄露的定义

如果某一段内存不能被外部访问,那么这段内存就是泄露了,可以说在这个进程的生命周期里,这段内存就白白浪费了,一般泄露是不会造成系统速度变慢的,只是浪费了内存空间。


而war3里的handle泄露会变慢的原因,不是因为泄露,而是war3每次新建一个handle值时都要搜索handle表(估计是这个算法太差了),当handle表很大时,每新建一个handle值都会很慢,如果某一个点用完后,没删取,那么它还是会在handle表里,当你有很多没删除的点时,handle表就会很大,速度就变得很慢了。这也是删除后必须set null的原因
回复

使用道具 举报

 楼主| 发表于 2008-8-4 13:34:53 | 显示全部楼层
(被自己忍无可忍的和谐掉了)
回复

使用道具 举报

发表于 2008-8-4 13:39:35 | 显示全部楼层

Re:【急!!】在StoreXXXX和GetStoredXXXX中使用string的"+"会导

很少??

你倒是说说哪个地图有100万字符串
回复

使用道具 举报

 楼主| 发表于 2008-8-4 13:59:07 | 显示全部楼层
(被自己忍无可忍的和谐掉了)
回复

使用道具 举报

发表于 2008-8-4 14:22:02 | 显示全部楼层
相同的字符串只算一次
回复

使用道具 举报

发表于 2008-8-4 14:28:09 | 显示全部楼层
另外,正如4楼所说,字符串只要出现,不能删除,所以你这样做是没用的,set s=null也是无用功,string不是handle,要想避免,就改进算法
回复

使用道具 举报

 楼主| 发表于 2008-8-4 14:30:43 | 显示全部楼层
(被自己忍无可忍的和谐掉了)
回复

使用道具 举报

发表于 2008-8-4 14:56:27 | 显示全部楼层
我又不知道你的技能是什么




不过如果不是十分必要,一般我会把变量绑定的在timer或trigger上
回复

使用道具 举报

 楼主| 发表于 2008-8-4 15:05:43 | 显示全部楼层
(被自己忍无可忍的和谐掉了)
回复

使用道具 举报

发表于 2008-8-4 15:20:33 | 显示全部楼层
话说不用+的原因应该是这样吧

War3中为String独立开辟一块内存区,初始分配的string地址为0-246,0=null 1="",2一般为地图名称,之后是各个用到的string。未使用的地址被赋值为"(null)"。
当分配的地址不够用时系统自动再分配256位地址,并全部赋值为"(null)"。
所有触发脚本中出现的字符串都会被记录,并无法删除。
相同的字符串不会被再次记录。

而且
设string内存地址1-25已被使用,那么
jass:  Copy codelocal string s
set s="a" //此时地址26被赋值为"a"
set s="b"+"c" //27="b" 28="c" 29="bc"
set s="bc" //"bc"已经存在,故不会再被记录
(详细找老狼的帖子)

你使用Return BUG来吧handle转成字符串的话
会制造很多新串(因为handle是数字很多口牙 理论上重复的几率很小)
加上上诉字符串+的算法 新串是很可观的
于是会消耗大量内存

不过还好处理字符串的内存是独立的
不影响其他方面 只是自己慢而已
但是最好还是避免用+ 因为这样产生的新串量是组合增长的
回复

使用道具 举报

发表于 2008-8-4 15:29:43 | 显示全部楼层
handle会循环使用的,只要不用H2S(handle)+“XX”这种形式,应该不会使字符串暴增
回复

使用道具 举报

发表于 2008-8-4 20:17:55 | 显示全部楼层
错了!不是100万条字符串,是100万条7位整数!,所以大概超过700万个字会卡,算一下每秒要创建100个字,要70000秒(超过19小时。。)才能卡。。
回复

使用道具 举报

发表于 2008-8-4 20:22:35 | 显示全部楼层
而且还不能有重复的。。
回复

使用道具 举报

发表于 2008-8-4 21:51:13 | 显示全部楼层
LS肯定理解错了,搜索字符串的算法是和字符串的数量有关而和长度无关
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-9 10:00 , Processed in 0.124837 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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