这是什么问题呢.机器的内存有1G啊,再说VB6又没有VS2005那样占资源,C友们,这样的情况你们
有遇到吗------这可跟系统没关系哦--因为俺重装N次都会
16 个解决方案
#1
可能你的程序有很多对象使用后没有及时释放
#2
应该是你具体的代码问题。
#3
你是不是调用了什么API或者第三方控件,可能是资源没释放
*****************************************************************************
欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码)
http://feiyun0112.cnblogs.com/
*****************************************************************************
欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码)
http://feiyun0112.cnblogs.com/
#4
这种问题不一定是内存占用太多:试一试下面的代码:
Private Sub Command1_Click()
Dim a As String
a = InStr(1, "12dザa", "a", 1)
End Sub
#5
老张,上面那个一启动就内存错误啊,俺那个不是这问题,
问下老张,俺使用对象后需要释放吗,俺好像使用后没有释放哦
问下老张,俺使用对象后需要释放吗,俺好像使用后没有释放哦
#6
好像没释放o
#7
LZ:你可在使用对象后用下面语句:
Nothing
使用 Nothing 关键字被将对象变量从实际对象中分离开来。要使用 Set 语句将 Nothing 赋值给对象变量。例如:
Set MyObject = Nothing
几个对象变量可以引用同一个实际对象。当 Nothing 被赋值给一个对象变量时,该变量不再引用任何实际对象。当几个对象变量引用同一个对象时,只有将全部对象变量都设置成 Nothing 之后,与被引用的对象有关联的内存资源及系统资源才会被释放掉,在这里,或者明确使用 Set,或者在最后一个设置成 Nothing 的对象变量超出范围后隐含地使用 Set。
Nothing
使用 Nothing 关键字被将对象变量从实际对象中分离开来。要使用 Set 语句将 Nothing 赋值给对象变量。例如:
Set MyObject = Nothing
几个对象变量可以引用同一个实际对象。当 Nothing 被赋值给一个对象变量时,该变量不再引用任何实际对象。当几个对象变量引用同一个对象时,只有将全部对象变量都设置成 Nothing 之后,与被引用的对象有关联的内存资源及系统资源才会被释放掉,在这里,或者明确使用 Set,或者在最后一个设置成 Nothing 的对象变量超出范围后隐含地使用 Set。
#8
这叫内存泄漏,最常见的原因就是对象循环引用。看下面的例子
ParentClass
ChildClass
Form1
添加控件 Label 两个、Timer、CheckBox、CommandButton
如果 CheckBox 未选中,启动 Timer 后可以看到任务管理器中该进程的内存不停增长。
CheckBox 选中后就没有该问题了。
ParentClass
Option Explicit
Private m_Data(1023)
Public Child As ChildClass
ChildClass
Option Explicit
Private m_Data(1023)
Public Parent As ParentClass
Form1
添加控件 Label 两个、Timer、CheckBox、CommandButton
Option Explicit
Private m_LeakCount As Long
Private m_GoodCount As Long
Private m_NoLeak As Boolean
Private Sub Test()
Dim p As ParentClass, c As ChildClass
Set p = New ParentClass
Set c = New ChildClass
Set p.Child = c
Set c.Parent = p
If m_NoLeak Then
'内存泄漏的解决方法:解除循环引用
Set p.Child = Nothing
Set c.Parent = Nothing
End If
Set p = Nothing
Set c = Nothing
End Sub
Private Sub Check1_Click()
m_NoLeak = Check1.Value
End Sub
Private Sub Command1_Click()
Timer1.Enabled = Not Timer1.Enabled
Command1.Caption = IIf(Timer1.Enabled, "&Stop", "&Start")
End Sub
Private Sub Form_Load()
Timer1.Enabled = False
Timer1.Interval = 100
End Sub
Private Sub Timer1_Timer()
Test
If m_NoLeak Then
m_GoodCount = m_GoodCount + 1
Label2 = m_GoodCount
Else
m_LeakCount = m_LeakCount + 1
Label1 = m_LeakCount
End If
End Sub
如果 CheckBox 未选中,启动 Timer 后可以看到任务管理器中该进程的内存不停增长。
CheckBox 选中后就没有该问题了。
#9
是的.正如这位朋友所说.好多个窗体在Form_Unload中是用了Set Form1 = Nothing,因为好多窗体需要调用一个类,
那这样是正常还是错误呢,这位朋友能不能讲下~~谢谢了~!
#10
Tiger_Zhao兄台讲得好详细啊,太感谢了,俺要加分答谢~!
#11
Tiger_Zhao兄台这个好妙啊!
#12
释放引用对象当然可以减少内存的开销,不用一定要释放
#13
原来还可以不一定要释放 谢谢老张 加分答谢
#14
无论是显式地 Set ... Nothing,还是隐式地通过变量的生命周期自动解除对象引用,都没有直接地“释放”对象,只是减少了对象的引用计数。
在 COM 机制中,只要引用计数归来,就自动释放对象。本来这是为了避免对象多处引用时被提前释放。
但是对象的循环引用恰恰是这种机制的软肋,越复杂的对象模型这个问题越难处理,.Net 框架就完全推翻改成了垃圾回收机制。
在 COM 机制中,只要引用计数归来,就自动释放对象。本来这是为了避免对象多处引用时被提前释放。
但是对象的循环引用恰恰是这种机制的软肋,越复杂的对象模型这个问题越难处理,.Net 框架就完全推翻改成了垃圾回收机制。
#15
明白了。这么说来VB6做的东西里面要是含带复杂的对象模型,那不是问题越多越难处理。
原来.Net是垃圾回收机制。
原来.Net是垃圾回收机制。
#16
复杂度其实是看如何设计对象之间的引用关系。
1)比如有两个对象:发票、明细,发票包含一组明细——那么发票肯定需要引用明细(通过集合或数组来包含),但是发票通常作为一个整体处理——明细不需要对发票进行引用;因此没有循环引用的问题。
2)在比如双向链表:很明细前后节点之间有引用,那么释放链表时需要拆开整个链表。
只要记得凡是有循环引用的对象,都需要用特定的方法显式释放就可以了。
一点也不复杂。
1)比如有两个对象:发票、明细,发票包含一组明细——那么发票肯定需要引用明细(通过集合或数组来包含),但是发票通常作为一个整体处理——明细不需要对发票进行引用;因此没有循环引用的问题。
2)在比如双向链表:很明细前后节点之间有引用,那么释放链表时需要拆开整个链表。
sub FreeDLink(byref pHeader as LinkNode)
dim pThis as LinkNode, pNext as LinkNode
set pThis = pHeader
While Not pThis is nothing
set pNext = pThis.NextNode
set pThis.PrevNode = nothing
set pThis.NextNode = nothing
set pThis = pNext
wend
set pHeader = nothing
end sub
只要记得凡是有循环引用的对象,都需要用特定的方法显式释放就可以了。
一点也不复杂。
#1
可能你的程序有很多对象使用后没有及时释放
#2
应该是你具体的代码问题。
#3
你是不是调用了什么API或者第三方控件,可能是资源没释放
*****************************************************************************
欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码)
http://feiyun0112.cnblogs.com/
*****************************************************************************
欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码)
http://feiyun0112.cnblogs.com/
#4
这种问题不一定是内存占用太多:试一试下面的代码:
Private Sub Command1_Click()
Dim a As String
a = InStr(1, "12dザa", "a", 1)
End Sub
#5
老张,上面那个一启动就内存错误啊,俺那个不是这问题,
问下老张,俺使用对象后需要释放吗,俺好像使用后没有释放哦
问下老张,俺使用对象后需要释放吗,俺好像使用后没有释放哦
#6
好像没释放o
#7
LZ:你可在使用对象后用下面语句:
Nothing
使用 Nothing 关键字被将对象变量从实际对象中分离开来。要使用 Set 语句将 Nothing 赋值给对象变量。例如:
Set MyObject = Nothing
几个对象变量可以引用同一个实际对象。当 Nothing 被赋值给一个对象变量时,该变量不再引用任何实际对象。当几个对象变量引用同一个对象时,只有将全部对象变量都设置成 Nothing 之后,与被引用的对象有关联的内存资源及系统资源才会被释放掉,在这里,或者明确使用 Set,或者在最后一个设置成 Nothing 的对象变量超出范围后隐含地使用 Set。
Nothing
使用 Nothing 关键字被将对象变量从实际对象中分离开来。要使用 Set 语句将 Nothing 赋值给对象变量。例如:
Set MyObject = Nothing
几个对象变量可以引用同一个实际对象。当 Nothing 被赋值给一个对象变量时,该变量不再引用任何实际对象。当几个对象变量引用同一个对象时,只有将全部对象变量都设置成 Nothing 之后,与被引用的对象有关联的内存资源及系统资源才会被释放掉,在这里,或者明确使用 Set,或者在最后一个设置成 Nothing 的对象变量超出范围后隐含地使用 Set。
#8
这叫内存泄漏,最常见的原因就是对象循环引用。看下面的例子
ParentClass
ChildClass
Form1
添加控件 Label 两个、Timer、CheckBox、CommandButton
如果 CheckBox 未选中,启动 Timer 后可以看到任务管理器中该进程的内存不停增长。
CheckBox 选中后就没有该问题了。
ParentClass
Option Explicit
Private m_Data(1023)
Public Child As ChildClass
ChildClass
Option Explicit
Private m_Data(1023)
Public Parent As ParentClass
Form1
添加控件 Label 两个、Timer、CheckBox、CommandButton
Option Explicit
Private m_LeakCount As Long
Private m_GoodCount As Long
Private m_NoLeak As Boolean
Private Sub Test()
Dim p As ParentClass, c As ChildClass
Set p = New ParentClass
Set c = New ChildClass
Set p.Child = c
Set c.Parent = p
If m_NoLeak Then
'内存泄漏的解决方法:解除循环引用
Set p.Child = Nothing
Set c.Parent = Nothing
End If
Set p = Nothing
Set c = Nothing
End Sub
Private Sub Check1_Click()
m_NoLeak = Check1.Value
End Sub
Private Sub Command1_Click()
Timer1.Enabled = Not Timer1.Enabled
Command1.Caption = IIf(Timer1.Enabled, "&Stop", "&Start")
End Sub
Private Sub Form_Load()
Timer1.Enabled = False
Timer1.Interval = 100
End Sub
Private Sub Timer1_Timer()
Test
If m_NoLeak Then
m_GoodCount = m_GoodCount + 1
Label2 = m_GoodCount
Else
m_LeakCount = m_LeakCount + 1
Label1 = m_LeakCount
End If
End Sub
如果 CheckBox 未选中,启动 Timer 后可以看到任务管理器中该进程的内存不停增长。
CheckBox 选中后就没有该问题了。
#9
是的.正如这位朋友所说.好多个窗体在Form_Unload中是用了Set Form1 = Nothing,因为好多窗体需要调用一个类,
那这样是正常还是错误呢,这位朋友能不能讲下~~谢谢了~!
#10
Tiger_Zhao兄台讲得好详细啊,太感谢了,俺要加分答谢~!
#11
Tiger_Zhao兄台这个好妙啊!
#12
释放引用对象当然可以减少内存的开销,不用一定要释放
#13
原来还可以不一定要释放 谢谢老张 加分答谢
#14
无论是显式地 Set ... Nothing,还是隐式地通过变量的生命周期自动解除对象引用,都没有直接地“释放”对象,只是减少了对象的引用计数。
在 COM 机制中,只要引用计数归来,就自动释放对象。本来这是为了避免对象多处引用时被提前释放。
但是对象的循环引用恰恰是这种机制的软肋,越复杂的对象模型这个问题越难处理,.Net 框架就完全推翻改成了垃圾回收机制。
在 COM 机制中,只要引用计数归来,就自动释放对象。本来这是为了避免对象多处引用时被提前释放。
但是对象的循环引用恰恰是这种机制的软肋,越复杂的对象模型这个问题越难处理,.Net 框架就完全推翻改成了垃圾回收机制。
#15
明白了。这么说来VB6做的东西里面要是含带复杂的对象模型,那不是问题越多越难处理。
原来.Net是垃圾回收机制。
原来.Net是垃圾回收机制。
#16
复杂度其实是看如何设计对象之间的引用关系。
1)比如有两个对象:发票、明细,发票包含一组明细——那么发票肯定需要引用明细(通过集合或数组来包含),但是发票通常作为一个整体处理——明细不需要对发票进行引用;因此没有循环引用的问题。
2)在比如双向链表:很明细前后节点之间有引用,那么释放链表时需要拆开整个链表。
只要记得凡是有循环引用的对象,都需要用特定的方法显式释放就可以了。
一点也不复杂。
1)比如有两个对象:发票、明细,发票包含一组明细——那么发票肯定需要引用明细(通过集合或数组来包含),但是发票通常作为一个整体处理——明细不需要对发票进行引用;因此没有循环引用的问题。
2)在比如双向链表:很明细前后节点之间有引用,那么释放链表时需要拆开整个链表。
sub FreeDLink(byref pHeader as LinkNode)
dim pThis as LinkNode, pNext as LinkNode
set pThis = pHeader
While Not pThis is nothing
set pNext = pThis.NextNode
set pThis.PrevNode = nothing
set pThis.NextNode = nothing
set pThis = pNext
wend
set pHeader = nothing
end sub
只要记得凡是有循环引用的对象,都需要用特定的方法显式释放就可以了。
一点也不复杂。