进程内存工作集转友好格式失败,输出始终为1 Bytes问题排查
问题:为什么Get-Process的内存工作集显示为“1 Bytes”?
你写了一个Get-FriendlySize函数,用来把字节数转换成友好的大小格式,处理文件目录时输出完全正常:
正常工作的文件处理脚本
function Get-FriendlySize { param($Bytes) $sizes='Bytes,KB,MB,GB,TB,PB,EB,ZB' -split ',' for($i=0; ($Bytes -ge 1kb) -and ($i -lt $sizes.Count); $i++) { $Bytes/=1kb } $N=2; if($i -eq 0) {$N=0} "{0:N$($N)} {1}" -f $Bytes, $sizes[$i] } dir 'C:\Windows\ccmsetup' | Select-Object -Property Name, LastWriteTime, @{N='FriendlySize';E={Get-FriendlySize -Bytes $_.Length}}
文件处理的正常输出
Name LastWriteTime FriendlySize ---- ------------- ------------ cache 7/5/2017 10:47:32 AM 1 Bytes Logs 5/17/2018 5:18:28 PM 1 Bytes {6EF23B21-22B7-453C-A975-52723EE71ABA} 1/7/2018 1:06:03 PM 1 Bytes ccmsetup.cab 1/7/2018 1:04:21 PM 9.42 KB ccmsetup.exe 11/7/2017 8:00:00 PM 3.55 MB ...
但当你把这个逻辑用到Get-Process输出,想把内存工作集转成友好格式时,输出却始终是“1 Bytes”:
出错的进程处理脚本
function Get-FriendlySize { param($Bytes) $sizes='Bytes,KB,MB,GB,TB,PB,EB,ZB' -split ',' for($i=0; ($Bytes -ge 1kb) -and ($i -lt $sizes.Count); $i++) { $Bytes/=1kb } $N=2; if($i -eq 0) {$N=0} "{0:N$($N)} {1}" -f $Bytes, $sizes[$i] } Get-Process -Name explorer | Select-Object -Property Handles, @{N='RAM Working Set';E={Get-FriendlySize -Bytes $_.Length}}, CPU, Id, ProcessName
出错的输出
Handles : 2521 RAM Working Set : 1 Bytes CPU : 169.125 Id : 10080 ProcessName : explorer
错误原因分析
问题出在你引用了进程对象不存在的属性!
- 处理文件时,
dir返回的FileInfo/DirectoryInfo对象确实有Length属性,用来存储文件/目录的字节大小; - 但
Get-Process返回的Process对象,根本没有Length属性!当你调用$_.Length时,PowerShell会返回$null。
把$null传入Get-FriendlySize后:
- 循环条件
($Bytes -ge 1kb)会因为$null的比较结果为$false,直接跳过循环,$i保持为0; - 最后格式化输出时,PowerShell会把
$null隐式处理成特殊值,最终输出“1 Bytes”——但核心问题还是用错了属性。
进程的内存工作集对应的正确属性是WorkingSet(32位)或者WorkingSet64(64位,推荐使用,避免内存大小超过32位限制)。
修正后的脚本
把计算属性里的$_.Length替换成$_.WorkingSet64即可:
function Get-FriendlySize { param($Bytes) $sizes='Bytes,KB,MB,GB,TB,PB,EB,ZB' -split ',' for($i=0; ($Bytes -ge 1kb) -and ($i -lt $sizes.Count); $i++) { $Bytes/=1kb } $N=2; if($i -eq 0) {$N=0} "{0:N$($N)} {1}" -f $Bytes, $sizes[$i] } Get-Process -Name explorer | Select-Object -Property Handles, @{N='RAM Working Set';E={Get-FriendlySize -Bytes $_.WorkingSet64}}, CPU, Id, ProcessName
预期输出示例
Handles RAM Working Set CPU Id ProcessName ------- --------------- --- -- ----------- 2521 123.45 MB 169.125 10080 explorer
这样就能正确显示进程内存工作集的友好格式了。
内容的提问来源于stack exchange,提问作者user3342256
相关产品推荐
相关产品推荐

