When monitoring VMware vSphere environments, two critical memory metrics often indicate resource contention:
- Memory ballooning (vmmemctl): When the VMkernel reclaims memory from VMs using the balloon driver
- Memory swapping: When the hypervisor starts swapping VM memory to disk
Here's a comprehensive PowerCLI script that identifies problematic VMs across a cluster or resource pool:
# Connect to vCenter
Connect-VIServer -Server your_vcenter.example.com
# Function to get memory metrics
function Get-VMMemoryStatus {
param(
[Parameter(ValueFromPipeline=$true)]
$VM
)
process {
$memoryStats = $VM | Get-Stat -Stat 'mem.vmmemctl.average','mem.swapped.average' -Realtime -MaxSamples 1
$ballooned = ($memoryStats | Where-Object {$_.MetricId -eq 'mem.vmmemctl.average'}).Value
$swapped = ($memoryStats | Where-Object {$_.MetricId -eq 'mem.swapped.average'}).Value
[PSCustomObject]@{
VM = $VM.Name
BalloonedMB = if($ballooned) {[math]::Round($ballooned,2)} else {0}
SwappedMB = if($swapped) {[math]::Round($swapped,2)} else {0}
Cluster = $VM.VMHost.Parent.Name
ResourcePool = $VM.ResourcePool.Name
}
}
}
# Get all VMs with memory pressure
$problemVMs = Get-Cluster "Your_Cluster_Name" | Get-VM | Get-VMMemoryStatus |
Where-Object {$_.BalloonedMB -gt 0 -or $_.SwappedMB -gt 0} |
Sort-Object -Property BalloonedMB -Descending
# Output results
$problemVMs | Format-Table -AutoSize
# Alternative: Export to CSV for further analysis
$problemVMs | Export-Csv -Path "C:\Temp\MemoryPressureVMs.csv" -NoTypeInformation
The script outputs several key metrics:
- BalloonedMB: Memory reclaimed through balloon driver (in MB)
- SwappedMB: Memory swapped to disk (in MB)
- Cluster/ResourcePool: Location context for the VM
For large environments, you might want to filter results more precisely:
# Find VMs with significant ballooning (> 1GB)
$significantBallooning = $problemVMs | Where-Object {$_.BalloonedMB -gt 1024}
# Find VMs where swapped memory exceeds 5% of configured memory
$severeSwapping = Get-Cluster "Prod_Cluster" | Get-VM | ForEach-Object {
$metrics = $_ | Get-VMMemoryStatus
$totalRAM = $_.MemoryMB
if($metrics.SwappedMB -gt ($totalRAM * 0.05)) {
$metrics | Select-Object *,@{Name='SwappedPct';Expression={[math]::Round(($_.SwappedMB/$totalRAM)*100,2)}}
}
}
For proactive monitoring, integrate this with your alerting system:
# Thresholds for alerting (customize as needed)
$balloonThresholdMB = 512
$swapThresholdMB = 256
$alertVMs = $problemVMs | Where-Object {
$_.BalloonedMB -gt $balloonThresholdMB -or
$_.SwappedMB -gt $swapThresholdMB
}
if($alertVMs) {
# Send email alert
$body = $alertVMs | ConvertTo-Html | Out-String
Send-MailMessage -From "vmmonitor@example.com" -To "vteam@example.com"
-Subject "Memory Pressure Alert: $($alertVMs.Count) VMs affected"
-BodyAsHtml $body -SmtpServer "smtp.example.com"
# Alternatively, create vCenter alarms
$alertVMs | ForEach-Object {
New-AlarmDefinition -Name "Memory Pressure - $($_.VM)" -Description "High memory ballooning/swapping detected"
-Entity ($_ | Get-VM) -Action (New-AlarmAction -Snmp)
}
}
When running these queries in large environments:
- Use the
-Realtime
parameter for current data (20s interval) - For historical analysis, specify
-Start
and-Finish
parameters with-IntervalMins
- Limit scope when possible (cluster/resource pool vs entire vCenter)
For VMs identified with memory pressure:
- Right-size memory allocations based on actual usage
- Check for memory leaks in guest OS
- Consider vSphere Memory Reservations for critical workloads
- Evaluate cluster-level memory resources (DRS, HA settings)
When working with VMware vSphere clusters, memory ballooning (vmmemctl) and swapping occur when the ESXi host is under memory pressure. Ballooning is a preferred method where the VMkernel reclaims memory from guest VMs using the balloon driver, while swapping is a last-resort mechanism that can significantly impact performance.
The most efficient way to identify VMs with ballooned or swapped memory is through VMware's PowerCLI. Here's a comprehensive script that provides detailed information:
# Connect to vCenter Server
Connect-VIServer -Server your_vcenter_server -Credential (Get-Credential)
# Get all VMs with memory metrics
$report = @()
$vms = Get-VM | Where-Object {$_.PowerState -eq "PoweredOn"}
foreach ($vm in $vms) {
$metrics = Get-Stat -Entity $vm -Stat "mem.vmmemctl.average", "mem.swapped.average" -Realtime -MaxSamples 1
$ballooned = ($metrics | Where-Object {$_.MetricId -eq "mem.vmmemctl.average"}).Value
$swapped = ($metrics | Where-Object {$_.MetricId -eq "mem.swapped.average"}).Value
$report += [PSCustomObject]@{
VMName = $vm.Name
BalloonedMB = if ($ballooned) { [math]::Round($ballooned) } else { 0 }
SwappedMB = if ($swapped) { [math]::Round($swapped) } else { 0 }
Cluster = $vm.VMHost.Parent.Name
Host = $vm.VMHost.Name
}
}
# Display results sorted by most ballooned memory
$report | Sort-Object -Property BalloonedMB -Descending | Format-Table -AutoSize
# Export to CSV for further analysis
$report | Export-Csv -Path "C:\temp\VM_Memory_Usage.csv" -NoTypeInformation
The script outputs several key metrics:
- BalloonedMB: Shows how much memory (in MB) is currently being reclaimed through ballooning
- SwappedMB: Indicates the amount of memory swapped to disk
- Cluster/Host: Helps identify if issues are localized to specific hosts or clusters
For those who prefer working directly with the vSphere API, here's a Python example using pyVmomi:
from pyVmomi import vim
from pyVim.connect import SmartConnectNoSSL, Disconnect
import atexit
def get_vm_memory_stats(si):
content = si.RetrieveContent()
container = content.viewManager.CreateContainerView(
content.rootFolder, [vim.VirtualMachine], True)
for vm in container.view:
if vm.runtime.powerState == vim.VirtualMachinePowerState.poweredOn:
stats = vm.summary.quickStats
print(f"VM: {vm.name}")
print(f" Ballooned Memory: {stats.balloonedMemory} MB")
print(f" Swapped Memory: {stats.swappedMemory} MB")
print(f" Guest Memory Usage: {stats.guestMemoryUsage} MB")
print("------------------------")
# Connect to vCenter
si = SmartConnectNoSSL(
host="vcenter.example.com",
user="administrator@vsphere.local",
pwd="yourpassword")
atexit.register(Disconnect, si)
get_vm_memory_stats(si)
For enterprise environments, consider setting up alerts in vRealize Operations Manager with these recommended thresholds:
- Warning: Ballooned memory > 10% of configured VM memory
- Critical: Swapped memory > 5% of configured VM memory
- Immediate action: Swapped memory > 10% of configured VM memory
Once you've identified problematic VMs:
- Check for memory over-provisioning in the cluster
- Consider increasing VM memory allocation if justified by workload requirements
- Evaluate memory reservations for critical VMs
- Implement DRS rules to balance memory load across hosts
- Upgrade VMware Tools to ensure balloon driver is functioning optimally