Очистить память в vb6 - PullRequest
       6

Очистить память в vb6

0 голосов
/ 04 января 2019
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 КБ

После выполнения кода выше объем памяти, используемой нашей программой vb6: 386 836 КБ

Наше приближение использования памяти после выполнения кода: 320 МБ enter image description here Фактическое использование памяти и приблизительное использование памяти находятся в одном диапазоне ~ 300 МБ

однако, когда строка cc увеличивается до 126 символов, происходит огромный скачок в использовании памяти.

cc = String(126, "w")

Память, используемая нашей программой vb6 после выполнения кода: 700,04 МБ

Наше приближение использования памяти после выполнения кода: 320 МБ

enter image description here Использование памяти увеличивается от 320 МБ до 700 МБ. Аналогично, когда другие строки увеличиваются до 126 символов, объем памяти увеличивается в диапазоне ГБ и приводит к ошибкам «нехватки памяти». Также существует некоторая проблема с добавлением строки vb6. (http://www.aivosto.com/articles/stringopt2.html "Создание огромных струн")

Есть ли возможность обнаружить и очистить (освободить) эту неиспользуемую память в vb6?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Каждая конкатенация строк в VB будет выделять новую строку, а затем копировать данные, а затем отменять выделение оригинала, как только сможет.

Для быстрой и оптимизированной для конкатенации строк памяти используйте класс StringBuilder. Если вы выполняете значительное количество манипуляций со строкой, таких как конкатенации, удаления и замены, ваша производительность может получить выгоду от класса StringBuilder в пространстве имен System.Text.

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

0 голосов
/ 13 января 2019

Я действительно не знаю, что происходит, но это связано с внутренним содержимым того, что 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 МБ памяти.

Теперь, если мы переместим назначение 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 МБ, что действительно странно.

Таким образом, один из способов получить нормальное потребление памяти - это вывести назначение 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

Если у вас есть enoтьфу память, чтобы пережить момент, когда «правильный» и «раздутый» массив существуют одновременно, это также может быть решением.

Я действительно потерян, почему это происходит иначе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...