清除vb6中的内存

时间:2019-01-04 09:50:10

标签: string memory-management vb6

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 enter image description here 实际的内存使用量和近似的内存使用量在同一范围内〜300MB

但是,当将字符串cc增加到126个字符时,内存使用量将大大增加。

cc = String(126, "w")

vb6程序执行代码后使用的内存:700.04 MB

代码执行后我们的内存使用量近似值:320 MB

enter image description here 内存使用量从320 Mb激增到700 MB。类似地,当其他字符串增加到126个字符时,内存猛增到GB范围内,并导致“内存不足”错误。vb6字符串附加似乎也存在一些问题(http://www.aivosto.com/articles/stringopt2.html“构建巨大的字符串”)

是否可以选择检测并清除(取消分配)vb6中未使用的内存?

2 个答案:

答案 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类。

https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/operators-and-expressions/concatenation-operators