Option Explicit
Dim VBFlexGridCells() As String
Private Sub store_values()
On Error GoTo store_values_EH
Dim IndexLong As Long
Dim i As Integer
Dim entry As String
Dim rw As Integer
Dim aa As String
Dim bb As String
Dim cc As String
Dim dd As String
Dim ee As String
Dim jj As Integer
Dim ff As String
Dim ll As String
Dim mm As String
Dim nn As String
Dim kk As String
rw = 1
For rw = 0 To 15000
aa = String(10000, "w")
bb = String(125, "w")
cc = String(125, "w")
dd = String(125, "w")
ee = String(125, "w")
ff = String(125, "w")
kk = String(125, "w")
ll = String(125, "w")
mm = String(125, "w")
nn = String(125, "w")
entry = aa & Chr(9) & bb & Chr(9) & cc & Chr(9) & dd & Chr(9) & ee & Chr(9) & ff & Chr(9) & kk & Chr(9) & ll & Chr(9) & mm & Chr(9) & nn
IndexLong = IndexLong + 1
ReDim Preserve VBFlexGridCells(10, IndexLong)
Dim abc() As String
abc = Split(entry, vbTab)
For jj = LBound(abc) To UBound(abc)
VBFlexGridCells(jj, IndexLong) = abc(jj)
Next
Next
Exit Sub
store_values_EH:
MsgBox Err.Description & Space(10) & "store_values"
End Sub
在执行上述代码之前,我们的vb6程序使用的内存为:17,720 KB
执行上述代码后,我们的vb6程序使用的内存为386,836 KB
代码执行后我们的内存使用量近似值:320 MB 实际的内存使用量和近似的内存使用量在同一范围内〜300MB
但是,当将字符串cc增加到126个字符时,内存使用量将大大增加。
cc = String(126, "w")
vb6程序执行代码后使用的内存:700.04 MB
代码执行后我们的内存使用量近似值:320 MB
内存使用量从320 Mb激增到700 MB。类似地,当其他字符串增加到126个字符时,内存猛增到GB范围内,并导致“内存不足”错误。vb6字符串附加似乎也存在一些问题(http://www.aivosto.com/articles/stringopt2.html“构建巨大的字符串”)
是否可以选择检测并清除(取消分配)vb6中未使用的内存?
答案 0 :(得分:0)
我真的不知道发生了什么,但是它必须对entry
最终包含的内容以及如何将其写入数组进行内部处理。如果在entry
生成时构造数组,数组最终会消耗更多的内存-并且数组是唯一可以分配内存的东西,没有“泄漏”的情况。
为了更好地说明问题,让我们删除不需要的代码,简化数组边界声明,并将除entry
赋值之外的所有内容移出循环:
Private Sub store_values()
Dim entry As String
Dim rw As Long
Dim aa As String
Dim bb As String
Dim cc As String
Dim dd As String
Dim ee As String
Dim jj As Long
Dim ff As String
Dim ll As String
Dim mm As String
Dim nn As String
Dim kk As String
aa = String(10000, "w")
bb = String(125, "w")
cc = String(126, "w") ' Increased from 125 to 126
dd = String(125, "w")
ee = String(125, "w")
ff = String(125, "w")
kk = String(125, "w")
ll = String(125, "w")
mm = String(125, "w")
nn = String(125, "w")
ReDim VBFlexGridCells(0 To 9, 1 To 15000)
For rw = 1 To 15000
entry = aa & Chr(9) & bb & Chr(9) & cc & Chr(9) & dd & Chr(9) & ee & Chr(9) & ff & Chr(9) & kk & Chr(9) & ll & Chr(9) & mm & Chr(9) & nn
Dim abc() As String
abc = Split(entry, vbTab) ' Returns zero-based array
For jj = LBound(abc) To UBound(abc)
VBFlexGridCells(jj, rw) = abc(jj)
Next
Next
End Sub
运行此操作将消耗大约700 Mb的内存。
现在,如果我们将entry
分配移出循环:
ReDim VBFlexGridCells(0 To 9, 1 To 15000)
entry = aa & Chr(9) & bb & Chr(9) & cc & Chr(9) & dd & Chr(9) & ee & Chr(9) & ff & Chr(9) & kk & Chr(9) & ll & Chr(9) & mm & Chr(9) & nn
For rw = 1 To 15000
Dim abc() As String
abc = Split(entry, vbTab) ' Returns zero-based array
For jj = LBound(abc) To UBound(abc)
VBFlexGridCells(jj, rw) = abc(jj)
Next
Next
仅消耗约320 Mb,这确实很奇怪。
因此,获取正常内存消耗的一种方法是将entry
分配移出循环。
如果这不是一个选择(因为生产代码entry
在每个迭代中都是不同的),那么还有另一种方法:复制数组还可以优化其消耗的内存:
Dim temp_array(0 To 9, 1 To 15000) As String
For rw = 1 To 15000
entry = aa & vbTab & bb & vbTab & cc & vbTab & dd & vbTab & ee & vbTab & ff & vbTab & kk & vbTab & ll & vbTab & mm & vbTab & nn
Dim abc() As String
abc = Split(entry, vbTab) ' Returns zero-based array
For jj = LBound(abc) To UBound(abc)
temp_array(jj, rw) = abc(jj)
Next
Next
'Here we are consuming 700 Mb
VBFlexGridCells = temp_array ' Copying
'Here we are consuming 1020 Mb
End Sub ' Here we are consuming 320 Mb
如果在“适当的”和“膨胀的”数组同时存在的那一刻,您有足够的内存来生存,那也可能是一个解决方案。
我真的迷失了为什么否则会发生。
答案 1 :(得分:-2)
VB中的每个字符串连接都将分配一个新字符串,然后将数据复制过来,然后尽可能地取消分配原始字符串。
对于快速和内存优化的字符串连接,请使用StringBuilder类。如果您对字符串进行大量操作(例如串联,删除和替换),则您的性能可能会受益于System.Text命名空间中的StringBuilder类。