Инструменты для определения объема памяти в приложениях VB6 - PullRequest
12 голосов
/ 13 апреля 2009

Какие инструменты доступны для отнесения потребления памяти в приложении VB6 к его нескольким компонентам? Я могу получить память, занятую всем приложением, наблюдая за различными счетчиками (Private Bytes, Working Set и т. Д.), Например, в Process Explorer. Я хочу пойти еще глубже и понять, сколько памяти потребляют различные компоненты или объекты, созданные во время выполнения. Например, выясните, сколько памяти используется большой коллекцией, которая кэширует данные во время выполнения, и как она изменяется в зависимости от количества элементов в коллекции.

Ответы [ 4 ]

5 голосов
/ 17 апреля 2009

Мой любимый инструмент должен быть DevPartner, хотя за 1500 фунтов стерлингов он не дешев. Хотя это намного больше, чем проверка утечки памяти, но если это все, что вам нужно, вы можете быть муравьями-ковровыми бомбами.

Если вы хотите увидеть, правильно ли ваше приложение высвобождает ресурсы, используйте эту функцию, которую я написал, чтобы выгрузить память в определенном месте. Сначала я бы кешировал адреса каждой из ваших переменных, затем при выключении вы могли бы вызвать DumpVariableMemory, передавая ссылки на эти места, чтобы узнать, были ли они освобождены.

Если у вас его еще нет, вам также нужно добавить декларацию fopr CopyMemory:)

    Public Function DumpVariableMemory(ByVal lngVariablePointer&, _
                                   ByVal lngBufferSizeInBytes&) As String
    '' * Object Name:   DumpVariableMemory
    '' * Type:          Function
    '' * Purpose:       Returns a memory dump of the variable or pointer location
    '' * Created:       21/08/2006 - 17:41:32
    '' * Coder:         Richard Pashley - NUPUK00008148
    '' * Build Machine: W-XPRP-77
    '' * Encapsulation: Full
    '' * Parameters:    lngVariablePointer      -   Long    -   Pointer to the data to dump
    '' *                lngBufferSizeInBytes    -   Long    -   Size of the dump to ouput in bytes
    '' * Returns:       -                       -   String  -   Memory dump output as a string
    '' *                This will dump the memory location starting at the pointer address and
    '' *                ending at the address plus the offset (lngBufferSizeInBytes).
    '' *                You can use LenB to determine the size of the variable for the
    '' *                lngBufferSizeInBytes parameter if required.
    '' *                Example: DebugPrint DumpVariableMemory(VarPtr(lngMyLongValue),LenB(lngMyLongValue)
    '' * Modified By:   [Name]
    '' * Date:          [Date]
    '' * Reason:        [NUPUKxxxxxxxxx]
    '' Declare locals
    Dim lngBufferIterator&                  '' Buffer iterator
    Dim lngBufferInnerIterator&             '' Buffer loop inner iterator
    Dim bytHexDumpArray() As Byte           '' Received output buffer
    Dim strDumpBuffer$                      '' Formatted hex dump construction buffer
    Dim lngValidatedBufferSize&             '' Validated passed buffer size
    '' Turn on error handling
    On Error GoTo DumpVariableMemory_Err
    '' Resize output buffer
    ReDim bytHexDumpArray(0 To lngBufferSizeInBytes - 1) As Byte
    '' Retrieve memory contents from supplied pointer
    Call CopyMemory(bytHexDumpArray(0), _
       ByVal lngVariablePointer, _
       lngBufferSizeInBytes)
    '' Format dump header
    strDumpBuffer = String(81, "=") & vbCrLf & _
       "Pointer Address = &h" & Hex$(lngVariablePointer) & _
       "   Ouput Buffer Size = " & FormatBytes(lngBufferSizeInBytes)
    '' Add header seperator
    strDumpBuffer = strDumpBuffer & _
       vbCrLf & String(81, Chr$(61))
    '' Validate buffer dimensions
    If lngBufferSizeInBytes Mod 16 = 0 Then
        '' Validated ok so assign
        lngValidatedBufferSize = lngBufferSizeInBytes
    Else
        '' Refactor to base 16
        lngValidatedBufferSize = _
           ((lngBufferSizeInBytes \ 16) + 1) * 16
    End If
    '' Iterate through buffer contents
    For lngBufferIterator = 0 To (lngValidatedBufferSize - 1)
        '' Determine if first row
        If (lngBufferIterator Mod 16) = 0 Then
            '' Format dump output row
            strDumpBuffer = strDumpBuffer & vbCrLf & Right$(String(8, Chr$(48)) _
               & Hex$(lngVariablePointer + lngBufferIterator), 8) & Space(2) & _
               Right$(String(4, Chr$(48)) & Hex$(lngBufferIterator), 4) & Space(2)
        End If
        '' Determine required dump buffer padding
        If lngBufferIterator < lngBufferSizeInBytes Then
            '' Pad dump buffer
            strDumpBuffer = strDumpBuffer & Right$(Chr$(48) & _
               Hex(bytHexDumpArray(lngBufferIterator)), 2)
        Else
            '' Pad dump buffer
            strDumpBuffer = strDumpBuffer & Space(2)
        End If
        '' Determine required dump buffer padding
        If (lngBufferIterator Mod 16) = 15 Then
            '' Pad dump buffer
            strDumpBuffer = strDumpBuffer & Space(2)
            '' Iterate through buffer row
            For lngBufferInnerIterator = (lngBufferIterator - 15) To lngBufferIterator
                '' Validate row width
                If lngBufferInnerIterator < lngBufferSizeInBytes Then
                    '' Validate buffer constraints
                    If bytHexDumpArray(lngBufferInnerIterator) >= 32 And _
                       bytHexDumpArray(lngBufferInnerIterator) <= 126 Then
                        '' Ouput data to dump buffer row
                        strDumpBuffer = strDumpBuffer & _
                           Chr$(bytHexDumpArray(lngBufferInnerIterator))
                    Else
                        '' Pad dump buffer
                        strDumpBuffer = strDumpBuffer & Chr$(45)
                    End If
                End If
            Next
            '' Determine required dump buffer padding
        ElseIf (lngBufferIterator Mod 8) = 7 Then
            '' Pad dump buffer
            strDumpBuffer = strDumpBuffer & Chr$(45)
        Else
            '' Pad dump buffer
            strDumpBuffer = strDumpBuffer & Space(1)
        End If
    Next
    '' Assign result to function output
    DumpVariableMemory = strDumpBuffer & _
       vbCrLf & String(81, Chr$(61)) & vbCrLf
Exit_Point:
    Exit Function
    '' Error Handling
DumpVariableMemory_Err:
    LogError "modNYFixLibrary.DumpVariableMemory", Err.Number, Err.Description
    DumpVariableMemory = String(81, Chr$(61)) & vbCrLf & _
       "DumpFailed!" & vbCrLf & String(81, Chr$(61))
    GoTo Exit_Point
    Resume
End Function
2 голосов
/ 20 мая 2010

Memory Validator может сказать вам, где память выделена (и утечка) в программах VB6 (и C ++, C, Delphi, Fortran 95 ...).

2 голосов
/ 15 апреля 2009

Я не уверен, что какие-либо общедоступные (бесплатные) инструменты профилируют код VB6 до уровня модуля. Есть несколько профилей памяти, доступных для C / C ++ и .NET, но не так много на VB6, который я видел. Похоже, что все старые поставщики (IBM Purify, Compuware Devpartner / Boundschecker) в этой области либо выкуплены, либо перешли только на поддержку .NET.

Вы можете попробовать GlowCode . Он заявляет о поддержке C ++, но также подчеркивает родные образы x32 Win32.

Microsoft публикует DebugDiag , который поддерживает обнаружение утечек памяти для .NET или Win32, хотя я никогда не использовал его с VB. Возможно, он не показывает выдающиеся распределения на уровне модуля, но я бы поспорил, что он по крайней мере укажет, какие библиотеки / библиотеки выделили больше всего памяти.

1 голос
/ 14 апреля 2009

На сайте MS есть еще один инструмент под названием processmonitor.exe . Он сообщает о каждом вызове запроса, и вы можете использовать его возможность фильтрации только для отслеживания запросов процесса вашего приложения.

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