怎么样才能监控出到底是那段代码的哪些对象没有被释放呢?现在都不知掉这么庞大的代码中哪些没有set 对象=nothing,寻求帮助。
20 个解决方案
#1
事实上,set x=nothing并不是必须的,VB在退出过程时会自动清理,你可以编写代码测试,你没有设nothing,但是Class_Terminate()是会执行(意味着自己清理)。关键是,你不能使用循环引用,如果存在循环引用,那你就需要设置nothing
#2
循环引用前好象会自动set nothing
#3
对啊,所以不少对象还有专门的Close,Dispose这类方法啊
#4
这个比较不现实,
除非你将每个对象的生成与销毁都保存下来,写入文件,否者难。
除非你将每个对象的生成与销毁都保存下来,写入文件,否者难。
#5
我现在是这个程序一直开在那边,自动的执行里面很多模块,现在很准时,2天必定WINDOW报out of memory,然后电脑就内存溢出了,只能将这个程序强行关闭,就好了,遇到这个情况我应该怎么去解决呢?
#6
补充一下,是VB执行的时候抛出的ERROR是 OUT OF MEMORY,此时远程连到这台电脑上,发现电脑就是内存溢出了,就像我们平时电脑程序开多了,点什么都没反应
#7
建议楼主仔细检查每个对象,看看有没有使用了没有释放的地方。此外你也可以把你怀疑的地方设置一些写标记语言,把每次用对象的地方都记入文件,以便出问题的时候查阅。
#8
按VB6标准的函数与语句来写的话,基本上是不会出现内存泄漏吧,除非使用了非VB6管理以外的东东,比如自己调用API申请内存内存,创建句柄之类,这些不是VB6的管理范围,得编码者自己把握.
#9
set nothing那玩意真的没什么用,你new XXX他会自动先set nothing
#10
今天暴力测试了一下,将程序一直开着,然后不停的做操作,发现半小时后必定报out of memory,还是无从下手。
VB6有没有什么方法可以监控到out of memory时,到底是什么东西导致他这样的?
VB6有没有什么方法可以监控到out of memory时,到底是什么东西导致他这样的?
#11
+1
#12
按VB6标准的函数与语句来写的话,基本上是不会出现内存泄漏吧,除非使用了非VB6管理以外的东东,比如自己调用API申请内存内存,创建句柄之类,这些不是VB6的管理范围,得编码者自己把握.
循环引用这种情况释放不掉
他的情况应该出在编写者没有使用复制,全用成引用了,再要解开就麻烦了
该复制的时候还是要复制的
循环引用这种情况释放不掉
他的情况应该出在编写者没有使用复制,全用成引用了,再要解开就麻烦了
该复制的时候还是要复制的
#13
不要说没有用,我就经常用 set x=nothing,习惯了。
我还经常用 erase 清除数组,也习惯了。
养成动态回改内存是一种良好的习惯。
因为,计算机同时运行的软件有好多个。
我还经常用 erase 清除数组,也习惯了。
养成动态回改内存是一种良好的习惯。
因为,计算机同时运行的软件有好多个。
#14
'启动模块中打开日志文件
Option Explicit
Public g_hLogFile As Integer
Sub Main()
g_hLogFile = FreeFile()
Open App.Path & "\" & App.EXEName & ".log" For Append As #g_hLogFile
Form1.Show
End Sub
'Form1 主窗体退出时关闭日志
Private Sub Form_Unload(Cancel As Integer)
Set c1 = Nothing
Close #g_hLogFile
End Sub
'每个类都写日志:对象指针,类名,创建/释放
Option Explicit
Private Sub Class_Initialize()
Print #g_hLogFile, Hex(ObjPtr(Me)) & " Class1_Intialize()"
End Sub
Private Sub Class_Terminate()
Print #g_hLogFile, Hex(ObjPtr(Me)) & " Class1_Terminate()"
End Sub
最终日志如下,对比一下那些对象指针只有 Intialize 没有 Terminate 就是没有释放的。
[Quoto=日志:]3DF3F08 Class1_Intialize()
3DF3EC0 Class2_Intialize()
3DF3EC0 Class2_Terminate()
3DF3F08 Class1_Terminate()[/Quote]
#15
用这个日志就能看到循环引用的没有释放,这是自动化管理没有处理到的
dnet 用扫描算法来清理,吹嘘了好一阵
dnet 用扫描算法来清理,吹嘘了好一阵
#16
如老马所说检查API释放,并检查全局VB对象的释放(局部的会自动释放)。
#17
+1
这个问题我也遇到了!已经发帖。
#18
循环引用的话,引用计数始终不为零,加减不平衡,在当前对象变量范围内确实会引起内存洩漏.
不过当前范围退出后,这些引用计数也是会被清零的.
比如一个在窗体A内实例化的窗体级对象,无论怎样循环引用(除了API操作对象指针等),窗体实例被销毁时还是会被回收的.
但是如果这个对象不是窗体级的,而是全局范围内的,就只有退出程序才能回收了.
这个问题我觉得基本上还是与工程的结构有关系,如何管理代码,如何管理复杂度,就决定了工程能做多大同时还是在完全可控范围内.
这个技术与编码技术几乎无关,平时也很少有文章提及这些,大部分人几乎都是靠自己领悟...比较头疼,我现在工程大小的控制能力就比较小,汗,工程一大就开始乱了.
我见过某知名软件的部分源代码,VB6写的,400多兆,听说完全编译的话需要N台电脑折腾好多小时,真不知道他们如何进行复杂度管理的....
楼主这个问题,要彻底解决的话估计还是要找设计现在工程架构的人,找找结构上的问题,应该能看出点啥的,祝你好运....这可是个头疼的活.
#19
《高级Visual Basic编程(Advanced Visual Basic)》第六章 循环引用
一整章讲这个,足矣。
一整章讲这个,足矣。
#20
经过我一个礼拜的测试,似乎已经找到问题所在,只要将Form上的自定义控件拿掉,改用普通控件,暴力测试后没有发生此现象,现在的问题就在于这个user contorls中自己做的自定义控件应该也是个对象,但是对他set nothing说不支持此方法,请教各位自定义控件该怎么释放对象啊?
#21
#1
事实上,set x=nothing并不是必须的,VB在退出过程时会自动清理,你可以编写代码测试,你没有设nothing,但是Class_Terminate()是会执行(意味着自己清理)。关键是,你不能使用循环引用,如果存在循环引用,那你就需要设置nothing
#2
循环引用前好象会自动set nothing
#3
对啊,所以不少对象还有专门的Close,Dispose这类方法啊
#4
这个比较不现实,
除非你将每个对象的生成与销毁都保存下来,写入文件,否者难。
除非你将每个对象的生成与销毁都保存下来,写入文件,否者难。
#5
我现在是这个程序一直开在那边,自动的执行里面很多模块,现在很准时,2天必定WINDOW报out of memory,然后电脑就内存溢出了,只能将这个程序强行关闭,就好了,遇到这个情况我应该怎么去解决呢?
#6
补充一下,是VB执行的时候抛出的ERROR是 OUT OF MEMORY,此时远程连到这台电脑上,发现电脑就是内存溢出了,就像我们平时电脑程序开多了,点什么都没反应
#7
建议楼主仔细检查每个对象,看看有没有使用了没有释放的地方。此外你也可以把你怀疑的地方设置一些写标记语言,把每次用对象的地方都记入文件,以便出问题的时候查阅。
#8
按VB6标准的函数与语句来写的话,基本上是不会出现内存泄漏吧,除非使用了非VB6管理以外的东东,比如自己调用API申请内存内存,创建句柄之类,这些不是VB6的管理范围,得编码者自己把握.
#9
set nothing那玩意真的没什么用,你new XXX他会自动先set nothing
#10
今天暴力测试了一下,将程序一直开着,然后不停的做操作,发现半小时后必定报out of memory,还是无从下手。
VB6有没有什么方法可以监控到out of memory时,到底是什么东西导致他这样的?
VB6有没有什么方法可以监控到out of memory时,到底是什么东西导致他这样的?
#11
+1
#12
按VB6标准的函数与语句来写的话,基本上是不会出现内存泄漏吧,除非使用了非VB6管理以外的东东,比如自己调用API申请内存内存,创建句柄之类,这些不是VB6的管理范围,得编码者自己把握.
循环引用这种情况释放不掉
他的情况应该出在编写者没有使用复制,全用成引用了,再要解开就麻烦了
该复制的时候还是要复制的
循环引用这种情况释放不掉
他的情况应该出在编写者没有使用复制,全用成引用了,再要解开就麻烦了
该复制的时候还是要复制的
#13
不要说没有用,我就经常用 set x=nothing,习惯了。
我还经常用 erase 清除数组,也习惯了。
养成动态回改内存是一种良好的习惯。
因为,计算机同时运行的软件有好多个。
我还经常用 erase 清除数组,也习惯了。
养成动态回改内存是一种良好的习惯。
因为,计算机同时运行的软件有好多个。
#14
'启动模块中打开日志文件
Option Explicit
Public g_hLogFile As Integer
Sub Main()
g_hLogFile = FreeFile()
Open App.Path & "\" & App.EXEName & ".log" For Append As #g_hLogFile
Form1.Show
End Sub
'Form1 主窗体退出时关闭日志
Private Sub Form_Unload(Cancel As Integer)
Set c1 = Nothing
Close #g_hLogFile
End Sub
'每个类都写日志:对象指针,类名,创建/释放
Option Explicit
Private Sub Class_Initialize()
Print #g_hLogFile, Hex(ObjPtr(Me)) & " Class1_Intialize()"
End Sub
Private Sub Class_Terminate()
Print #g_hLogFile, Hex(ObjPtr(Me)) & " Class1_Terminate()"
End Sub
最终日志如下,对比一下那些对象指针只有 Intialize 没有 Terminate 就是没有释放的。
[Quoto=日志:]3DF3F08 Class1_Intialize()
3DF3EC0 Class2_Intialize()
3DF3EC0 Class2_Terminate()
3DF3F08 Class1_Terminate()[/Quote]
#15
用这个日志就能看到循环引用的没有释放,这是自动化管理没有处理到的
dnet 用扫描算法来清理,吹嘘了好一阵
dnet 用扫描算法来清理,吹嘘了好一阵
#16
如老马所说检查API释放,并检查全局VB对象的释放(局部的会自动释放)。
#17
+1
这个问题我也遇到了!已经发帖。
#18
循环引用的话,引用计数始终不为零,加减不平衡,在当前对象变量范围内确实会引起内存洩漏.
不过当前范围退出后,这些引用计数也是会被清零的.
比如一个在窗体A内实例化的窗体级对象,无论怎样循环引用(除了API操作对象指针等),窗体实例被销毁时还是会被回收的.
但是如果这个对象不是窗体级的,而是全局范围内的,就只有退出程序才能回收了.
这个问题我觉得基本上还是与工程的结构有关系,如何管理代码,如何管理复杂度,就决定了工程能做多大同时还是在完全可控范围内.
这个技术与编码技术几乎无关,平时也很少有文章提及这些,大部分人几乎都是靠自己领悟...比较头疼,我现在工程大小的控制能力就比较小,汗,工程一大就开始乱了.
我见过某知名软件的部分源代码,VB6写的,400多兆,听说完全编译的话需要N台电脑折腾好多小时,真不知道他们如何进行复杂度管理的....
楼主这个问题,要彻底解决的话估计还是要找设计现在工程架构的人,找找结构上的问题,应该能看出点啥的,祝你好运....这可是个头疼的活.
#19
《高级Visual Basic编程(Advanced Visual Basic)》第六章 循环引用
一整章讲这个,足矣。
一整章讲这个,足矣。
#20
经过我一个礼拜的测试,似乎已经找到问题所在,只要将Form上的自定义控件拿掉,改用普通控件,暴力测试后没有发生此现象,现在的问题就在于这个user contorls中自己做的自定义控件应该也是个对象,但是对他set nothing说不支持此方法,请教各位自定义控件该怎么释放对象啊?