读书人

VB怎么释放大内存

发布时间: 2012-01-22 22:38:43 作者: rapoo

VB如何释放大内存
废话少说,看代码:

测试工程1:
------------------------
类ct代码
------------------------

Option Explicit


Private m_lngV2 As Long
Private m_lngV1 As Long
Private m_lngV3 As Long
Private m_lngV4 As Long
Private m_lngV5 As Long
Private m_lngV6 As Long
Private m_lngV7 As Long
Private m_lngV8 As Long
Private m_lngV9 As Long

Public Property Get V9() As Long
V9 = m_lngV9
End Property

Public Property Let V9(ByVal lngValue As Long)
m_lngV9 = lngValue
End Property

Public Property Get V8() As Long
V8 = m_lngV8
End Property

Public Property Let V8(ByVal lngValue As Long)
m_lngV8 = lngValue
End Property

Public Property Get V7() As Long
V7 = m_lngV7
End Property

Public Property Let V7(ByVal lngValue As Long)
m_lngV7 = lngValue
End Property

Public Property Get V6() As Long
V6 = m_lngV6
End Property

Public Property Let V6(ByVal lngValue As Long)
m_lngV6 = lngValue
End Property

Public Property Get V5() As Long
V5 = m_lngV5
End Property

Public Property Let V5(ByVal lngValue As Long)
m_lngV5 = lngValue
End Property

Public Property Get V4() As Long
V4 = m_lngV4
End Property

Public Property Let V4(ByVal lngValue As Long)
m_lngV4 = lngValue
End Property

Public Property Get V3() As Long
V3 = m_lngV3
End Property

Public Property Let V3(ByVal lngValue As Long)
m_lngV3 = lngValue
End Property

Public Property Get V1() As Long
V1 = m_lngV1
End Property

Public Property Let V1(ByVal lngValue As Long)
m_lngV1 = lngValue
End Property

Public Property Get V2() As Long
V2 = m_lngV2
End Property

Public Property Let V2(ByVal lngValue As Long)
m_lngV2 = lngValue
End Property

Public Sub SetValue(v() As Long)
m_lngV1 = v(0)
m_lngV2 = v(1)
m_lngV3 = v(2)
m_lngV4 = v(3)
m_lngV5 = v(4)
m_lngV6 = v(5)
m_lngV7 = v(6)
m_lngV8 = v(7)
m_lngV9 = v(8)
End Sub

-----------------------
类cts代码
-----------------------
Option Explicit

Private m_Colcts As Collection


Private Sub Class_Initialize()

Set m_Colcts = New Collection

End Sub

Sub Add(CtItem As ct, Optional varKey As Variant)

m_Colcts.Add CtItem, varKey

End Sub

Sub Remove(varIndex As Variant)

m_Colcts.Remove varIndex

End Sub

Function Item(varIndex As Variant) As ct

Set Item = Nothing

On Error Resume Next
Set Item = m_Colcts.Item(varIndex)
On Error GoTo 0

End Function

Function Exists(varIndex As Variant) As Boolean

Dim objTest As ct
Set objTest = Nothing

If Count > 0 Then

On Error Resume Next
Set objTest = Item(varIndex)
On Error GoTo 0

End If

Exists = Not (objTest Is Nothing)

End Function


Property Get Count() As Long

Count = m_Colcts.Count

End Property


Sub Clear()

Set m_Colcts = New Collection

End Sub

Function NewEnum() As IUnknown

Set NewEnum = m_Colcts.[_NewEnum]

End Function



-----------------------
Form1代码
-----------------------


Option Explicit

Private ts As cts

Private Sub Command1_Click()

Set ts = New cts

Dim i As Long
Dim t As ct
Dim a(0 To 8) As Long

For i = 0 To 8

a(i) = i

Next

Me.Timer1.Enabled = True

For i = 1 To 1000000

Set t = New ct

DoEvents

Me.Text1.Text = i

t.SetValue a

ts.Add t

Next

Me.Timer1.Enabled = False
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim p As ct
For Each p In ts

DoEvents

Set p = Nothing

Next

Set ts = Nothing
End Sub

------------------
注:
------------------
窗体Form1上放一个Command1,一个Text1

-------------------
问题
-------------------
关闭程序时无响应,占用的一大块内存没有被释放。

高手都来发表下意见吧……



[解决办法]

VB code
For i = 1 To 1000000             Set t = New ct
[解决办法]
不知直接.Clear下内存会是怎么?
[解决办法]
做个延时1000毫秒之类的试试吧,
[解决办法]
VB code
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)    Dim i As Long    For i = ts.Count To 1 Step -1        ts.Remove i    Next    Set ts = NothingEnd Sub
[解决办法]
其实加一个按钮

Private Sub Command2_Click()
Set ts = Nothing
End Sub

盯着任务管理器,你会发现内存的确是被释放了,只不果释放速度比创建的时候慢
[解决办法]
这个。。。。
[解决办法]
又不是C,何必操心释放内存的事情
[解决办法]
VB结束后即刻释放内存,但操作系统不一定遵照执行,因为操作系统为优化下次运行该程序的速度会将释放的内存标记为缓冲区,所以数字上看不出。
[解决办法]
给你一段代码,效果立杆见影,用在以觉得内存比较大,需要释放一下的时候
VB code
'释放内存,常用于第一次启动完窗体后,效果显著Private Declare Function SetProcessWorkingSetSize Lib "kernel32" (ByVal hProcess As Long, ByVal dwMinimumWorkingSetSize As Long, ByVal dwMaximumWorkingSetSize As Long) As LongPrivate Declare Function GetCurrentProcess Lib "kernel32" () As LongPrivate Sub releasemem()   SetProcessWorkingSetSize GetCurrentProcess, -1, -1End Sub
[解决办法]
退出时直接调用End语句让操作系统自动释放你这个进程占用的内存试试。
[解决办法]
你Form1的代码贴全了么?timer似乎不是这样的用法哦
[解决办法]
友情UP......................

啥东东这么耗内存?运行过程中还要考虑内存释放?

[解决办法]
LZ要创建1000000个ct?? 你的代码本身就存在问题,是逻辑问题!

你向内存一下子申请这么多内存地址块,写代码的那个人不是有病吗?和电脑开国际玩笑是吧,可惜它不能像你一样会笑啊!
------解决方案--------------------


我把楼主的程序调试状态下直接END了,现在VB里的鼠标还在沙漏状态,好几分钟了。

记得这个问题我似乎也遇到过,也是做测试,一下子建立大量对象,New的时候快,结束程序的时候要慢很多。
[解决办法]
汗,貌似把我同时开着的VBA IDE也弄死了
[解决办法]

探讨
我把楼主的程序调试状态下直接END了,现在VB里的鼠标还在沙漏状态,好几分钟了。

记得这个问题我似乎也遇到过,也是做测试,一下子建立大量对象,New的时候快,结束程序的时候要慢很多。

[解决办法]
我测试的结果是,每释放1000个对象大约需要1、2分钟。测试代码参照口香糖7楼的回复修改如下:

VB code
Private Sub Form_Unload(Cancel As Integer)    Dim i As Long    Dim sngStart As Single        Screen.MousePointer = vbHourglass    sngStart = Timer    For i = ts.Count To 1 Step -1        If i Mod 1000 = 0 Then            Debug.Print Timer - sngStart            DoEvents            sngStart = Timer        End If        ts.Remove i    Next    Set ts = Nothing    Debug.Print Timer - sngStart    Screen.MousePointer = vbDefaultEnd Sub
[解决办法]
探讨
我测试的结果是,每释放1000个对象大约需要1、2分钟。

[解决办法]
TerminateProcess 直接杀掉,内存会很快释放````
[解决办法]
实际开发中肯定不会有这么多没有消灭的对象对不?创建一个用完就杀掉,程序顶多有几个全局的对象存在,占不了多少内存的。
[解决办法]
帮你顶一下:)
[解决办法]
好长的代码 没空看了 你看看有没有被循环引用了 我隐约看到了一个parent属性
[解决办法]
用END命令,让系统自己来释放,一了百了!
[解决办法]
产生楼主的问题的根源是:
  楼主的类对象 这里 Set m_Childs ,那里 Set m_Parent ,造成对象之间的循环引用。
  最终的后果就是:对象在运行期间无法被释放!
  所以,运行时,内存占用越来越多。


  楼主试一下下面的这段代码(按 32F 的窗体代码修改的,类代码没动),无论你点多少次按钮,开始时内存会增加(通过任务管理器来看的),但增加一定的数量后就不再增涨了(增加量不算多)。
  但是,如果没有我添加的那几句代码,就会内存占用‘无限增涨’(也许是,我不可能让我的系统 GAME OVER)。


VB code
Private Sub Command1_Click()        Me.Command1.Enabled = False        Dim tCas As CAs    Set tCas = New CAs        Dim tCa As CA    Dim iCa As Integer        For iCa = 1 To 100   '我改到 100 了。            Set tCa = New CA        tCa.IndexKey = "a" & iCa        Dim tCb As CB        Dim iCb  As Long        For iCb = 1 To 50            Set tCb = New CB            tCb.IndexKey = "b" & iCb            tCa.Childs.Add tCb            Set tCb = Nothing        Next        tCas.Add tCa        Set tCa = Nothing            Next        '做要做的事    Debug.Print tCas.Count, tCas.Item(1).Childs.Count        '做完了释放    ' ****** 楼主注意比较有这段代码和没这段代码的区别 ******    Dim i&, k&    For i = tCas.Count To 1 Step -1        For k = tCas.Item(i).Childs.Count To 1 Step -1            tCas.Item(i).Childs.Remove tCas.Item(i).Childs.Item(1).IndexKey        Next        Set tCas.Item(i).Childs.Category = Nothing        tCas.Remove tCas.Item(i).IndexKey    Next    ' *******************************************************    Set tCas = Nothing        Me.Command1.Enabled = True    End Sub
[解决办法]
我不清楚楼主的类代码为何要那样写。

但觉得这种类代码,简单地 set Noting ,不能正确释放对象。

[解决办法]
探讨
我不清楚楼主的类代码为何要那样写。

但觉得这种类代码,简单地 set Noting ,不能正确释放对象。


------解决方案--------------------


还是因为引用没释放,对象也不能被释放。

类 cts 的 m_Colcts .............

[解决办法]

探讨
还是因为引用没释放,对象也不能被释放。

类 cts 的 m_Colcts .............


[解决办法]
探讨
引用:
还是因为引用没释放,对象也不能被释放。

类 cts 的 m_Colcts .............



我用22楼办法释放的,也没用。
cts是个典型的集合类,通常都是那样做的,我看不出有什么问题。

[解决办法]
刚才试了一下,对象个数很多时,释放速度比较慢,速度很少时非常快。

原因应该是:
m_Colcts对象 的 .Remove 在对象很多的时候很耗时。

[解决办法]
关注....
[解决办法]
探讨
用END命令,让系统自己来释放,一了百了!

[解决办法]
end干什么?直接提升权限(Vista)然后强制终结System进程!
[解决办法]
楼主的意思估计是,在不关闭的情况下释放内存占用.

类似IIS的回收内存池功能一样......

要是关闭程序来实现,讨论就没意义了不是?呵呵.....

至于楼主的问题,我估计还是有对象未释放造成的.

比如你的类里面有没有使用别的类?释放没?然后里面的"别的类"呢?有没有类似的递归引用问题?
[解决办法]
路过帮顶

[解决办法]
高手啊。。。看不懂
[解决办法]
顶一下~~~~~~~~~~~~~~~~~~~~~~~
[解决办法]
确认一下,你的对象里面有没有用到模块级的不定数组?
如果有的话记住在对象使用完成以后 erase一下,否则即使set nothing了内存也不会释放的
[解决办法]
JF
[解决办法]
长见识啦。\(^o^)/~谢啦
[解决办法]
这么长的代码...啊...汗
[解决办法]
C++语言的设计和演化
[解决办法]
HENHAO!
[解决办法]
好,挣分
[解决办法]

[解决办法]
探讨
LZ要创建1000000个ct?? 你的代码本身就存在问题,是逻辑问题!

你向内存一下子申请这么多内存地址块,写代码的那个人不是有病吗?和电脑开国际玩笑是吧,可惜它不能像你一样会笑啊!

[解决办法]
学习了


[解决办法]
up
[解决办法]
每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分

[解决办法]
看看
[解决办法]
vb本身做不到运行中动态释放内存?

读书人网 >VB

热点推荐