• 如何對應某程式記憶體使用狀態

說明

    這個程式可以用來對映出某程式記憶體使用的情況,主要是使用 VirtualQueryEx這個API去對應每個記憶體區塊,這個和數有4個參數
     hProcess
         對應Process的Handle
       pAddress
           記憶體位址
       lpBuffer
           指向MEMORY_BASIC_INFORMATION結構的變數
       dwLength
          lpBuffer資料的大小

    而MEMORY_BASIC_INFORMATION結構 這個程式用到的部分有
    BaseAddress : 基底位址
    State : 配置狀態
    RegionSize : 區塊大小
    Protect : 屬性 有 E,R,W(可執行,可讀,可寫)三種屬性

    其他部分可以參考MSDN上的說明

    這個程式只有對應前端2GB的部分 如果要對應全部(4GB) 必須加上一點點進位的轉換 提示一下
    對應後半部時 tmpBassAddr要減去(2147483648# + 2147483648#)
    然對應部分程式一樣 除了跳出迴圈的If要改成tmpBassAddr >= 0 這樣就行了 不過由於執行時間很長 如果有需要再自行修改 因為2GB後是系統區段 我就省略啦

程式

    '----------------------------------------------------------------------------------------------
    ' 這個程式需要2個Text 和1個Command
    ' Text1 : 用來輸入視窗的標題 要對映記事本 只要在此輸入記事本
    ' Text2 : 用來輸出結果
    ' 將Text2的ScrollBars屬性設成3,MultiLine屬性設成True
    ' ----------------------------------------------------------------------------------------------
    Option Explicit
    Private Type MEMORY_BASIC_INFORMATION
         BaseAddress As Long
         AllocationBase As Long
         AllocationProtect As Long
         RegionSize As Long
         State As Long
         Protect As Long
         lType As Long
    End Type
    Private Declare Function VirtualQueryEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
    Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Private Const SYNCHRONIZE = &H100000
    Private Const SPECIFIC_RIGHTS_ALL = &HFFFF
    Private Const STANDARD_RIGHTS_ALL = &H1F0000
    Private Const PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF

    Private Const MEM_COMMIT = &H1000
    Private Const MEM_FREE = &H10000
    Private Const MEM_RESERVE = &H2000

    Private Const PAGE_NOACCESS = &H1
    Private Const PAGE_READONLY = &H2
    Private Const PAGE_READWRITE = &H4
    Private Const PAGE_WRITECOPY = &H8
    Private Const PAGE_EXECUTE = &H10
    Private Const PAGE_EXECUTE_READ = &H20
    Private Const PAGE_EXECUTE_READWRITE = &H40
    Private Const PAGE_EXECUTE_WRITECOPY = &H80
    Private Const PAGE_GUARD = &H100
    Private Const PAGE_NOCACHE = &H200

    Private Const SEC_IMAGE = &H1000000
    Private Const MEM_MAPPED = &H40000
    Private Const MEM_PRIVATE = &H20000
    Private Const MEM_IMAGE = SEC_IMAGE

    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" _
    (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Dim mbi As MEMORY_BASIC_INFORMATION
    Dim sOPT As String

    Private Sub Command1_Click()
    Dim hwnd As Long, hProcessID As Long, hProcess As Long
    Dim tmpBassAddr As Double, lBassAddr As Long
    hwnd = FindWindow(vbNullString, Text1.Text)
    Call GetWindowThreadProcessId(hwnd, hProcessID)
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, hProcessID)
    sOPT = "Begin List Process Memory Usage" & vbCrLf
    sOPT = sOPT & "Process ID:" & hProcessID & vbCrLf
    sOPT = sOPT & "位址" & Space(3) & "配置情況" & Space(3) & "屬性" & Space(3) & "大小" & vbCrLf
    Do While True
        sOPT = sOPT & Hex(tmpBassAddr) & Space(3)
        Call VirtualQueryEx(hProcess, ByVal lBassAddr, mbi, Len(mbi))
        Call PrintProperty '印出記憶體屬性
        tmpBassAddr = mbi.BaseAddress
        tmpBassAddr = tmpBassAddr + mbi.RegionSize
        If tmpBassAddr > &H7FFFFFFF Then '預防溢位
            Exit Do
        End If
        lBassAddr = tmpBassAddr '對應下一筆
    Loop
    Text2.Text = sOPT
    CloseHandle hProcess
    End Sub

    Private Sub Form_Load()
    Text1.Text = Me.Caption
    Text2.ScrollBars = 3
    Text2.MultiLine = True
    Command1.Caption = "列出記憶體使用狀態"
    End Sub
    Private Sub PrintProperty()
    Select Case mbi.State
        Case MEM_COMMIT
            sOPT = sOPT & "已配置"
        Case MEM_FREE
            sOPT = sOPT & "Free"
        Case MEM_RESERVE
            sOPT = sOPT & "保留"
        Case Else
            sOPT = sOPT & "不明"
    End Select

    sOPT = sOPT & Space(3)

    Select Case mbi.Protect
        Case PAGE_NOACCESS
            sOPT = sOPT & "---"
        Case PAGE_READONLY
            sOPT = sOPT & "-R-"
        Case PAGE_READWRITE
            sOPT = sOPT & "-RW"
        Case PAGE_EXECUTE
            sOPT = sOPT & "E--"
        Case PAGE_EXECUTE_READ
            sOPT = sOPT & "ER-"
        Case PAGE_EXECUTE_READWRITE
            sOPT = sOPT & "ERW"
        Case PAGE_EXECUTE_WRITECOPY
            sOPT = sOPT & "ERW"
        Case PAGE_WRITECOPY
            sOPT = sOPT & "--W"
        Case PAGE_GUARD
            sOPT = sOPT & "G"
        Case PAGE_NOCACHE
            sOPT = sOPT & "---"
        Case Else
            sOPT = sOPT & "不明"
    End Select
    sOPT = sOPT & Space(3)
    sOPT = sOPT & mbi.RegionSize \ 1024 & "KB" & vbCrLf
    End Sub

文件出處

      Honey

整理時間

      2001'12,1.

VB心得筆記歡迎各位的指教,如果您有任何文章或資料願意提供給我們的,請來信到VBNote

如果對本站有任何建議,歡迎來信給Honey,我們會盡快給您答覆