Forum Discussion

Daniel_Pineault's avatar
Dec 06, 2023

Need help determine Total Allocated Virtual Memory

I'm trying to determine the Total Allocate Virtual Memory of a Process but can't seem to find any examples.

 

I know I can do

 

Get-Process -Name 'MyProcessName' | Format-Table ` @{Label = "VM(M)"; Expression = {[int]($_.VM / 1MB)}}

 

to retrieve the currently used virtual memory, but I'd like to also retrieve the total available memory for the same process.

 

I know MemoryStatusEx should provide such information, but not sure how I can use it in PS or if I'm simply missing some built-in cmdlet that can do this?

 

Ideally, I'd love to be able to list a process of series of process and list (VM - virtual memory)

 

Process Name | Total VM | Used VM | Remaining VM

  • LeonPavesic's avatar
    LeonPavesic
    Silver Contributor

    Hi Daniel_Pineault,

    you can try to use the following PowerShell script to export all processes with Process Name, Total VM, Used VM and Remaining VM:

    $processes = Get-Process
    
    foreach ($process in $processes) {
        $totalVM = $process.VirtualMemorySize64 / 1MB
        $usedVM = $process.WorkingSet64 / 1MB
        $remainingVM = $totalVM - $usedVM
    
        $process | Format-Table @{Label = "Process Name"; Expression = {$_.Name}},
                                @{Label = "Total VM(MB)"; Expression = {$totalVM}},
                                @{Label = "Used VM(MB)"; Expression = {$usedVM}},
                                @{Label = "Remaining VM(MB)"; Expression = {$remainingVM}}
    }

      


    If you like it better, you can use the same script, but to export all the data in CSV file:

    $processes = Get-Process
    
    $output = foreach ($process in $processes) {
        $totalVM = $process.VirtualMemorySize64 / 1MB
        $usedVM = $process.WorkingSet64 / 1MB
        $remainingVM = $totalVM - $usedVM
    
        [PSCustomObject]@{
            "Process Name" = $process.Name
            "Total VM(MB)" = $totalVM
            "Used VM(MB)" = $usedVM
            "Remaining VM(MB)" = $remainingVM
        }
    }
    
    $output | Export-Csv -Path "ProcessInfo.csv" -NoTypeInformation

     


    Please click Mark as Best Response & Like if my post helped you to solve your issue.
    This will help others to find the correct solution easily. It also closes the item.


    If the post was useful in other ways, please consider giving it Like.


    Kindest regards,


    Leon Pavesic
    (LinkedIn)

    • Daniel_Pineault's avatar
      Daniel_Pineault
      MVP
      This doesn't match up with what I get using MemoryStatusEx Api.

      With this script I'm getting

      Process Name Total VM(MB) Used VM(MB) Remaining VM(MB)
      ------------ ------------ ----------- ----------------
      EXCEL 617.43359375 104.98046875 512.453125

      Yet via MemoryStatusEx I get
      Memory available: ( 2047 MB) - allocated: (594 MB) - free: ( 1453 MB)

      The Memory available of 2GB makes sense for a 32-bit app, so I have tendency to believe the API, but wish to do this via PS. Do you know why the numbers don't match up?
      • LainRobertson's avatar
        LainRobertson
        Silver Contributor

        Daniel_Pineault 

         

        Hi, Daniel.

         

        I don't believe there is any parallel to be found in .NET, and therefore none in PowerShell (which really just overlays .NET).

         

        While not confirmed by the class documentation, the second paragraph in the following article does state "performance information such as the amount of memory the process is using":

         

         

        My understanding of the [System.Process] class is that it pulls the memory statistics from the various Process\Memory counters (which all end in "64", i.e. WorkingSet64) and it therefore subservient to the  Windows performance management framework.

         

        The .NET results correlate those produced by SysInternals' pslist64.exe (with the exclusion of private working set, which is excluded from the .NET class for some reason).

         

        I'm definitely not privy to how the counters themselves are maintained, but anecdotally, neither .NET nor pslist.exe seem to use the WinAPI function you mentioned given the results don't match.

         

        If that is indeed the case then all you can do is write your own function in PowerShell that actions a P/Invoke call to that function after the necessary types have been defined and imported.

         

        P/Invoking is an ugly business and not something I look to leverage, but if you can handle the pain, you can get the outcome you're seeking.

         

         

        Cheers,

        Lain

         

Resources