【问题标题】:PowerShell Single Line Huge Memory UsagePowerShell 单行占用大量内存
【发布时间】:2022-12-02 23:41:58
【问题描述】:

我正在尝试使用以下命令。每当我使用它时,内存使用率都非常高。有没有办法在完成相同任务的同时降低内存使用率?

Get-ChildItem -Path ("C:\") -r |
  sort -descending -property length | 
  select -first 20 fullname, @{Name="Gigabytes";Expression={[Math]::round($_.length / 1GB, 2)}

【问题讨论】:

  • 1. 从"C:" 周围移除括号()。 2. 是 -r 应该是 -Recurse 还是 -ReadOnly - 它不明确,命令应该失败。如果它是-Recurse,那么就没有办法在保持单行或不使用临时文件的情况下减少内存; Sort-Object 如果没有在内存中排序所需的所有内容并进行搜索,则无法排序全部C: 上的大量文件将导致大量文件,即使在新安装的 Windows 系统上也是如此。
  • 感谢您的回复,-r 用于递归。命令本身有效;它只会占用大量内存。我希望能够找到硬盘驱动器上最大的文件,并按照从大到小的顺序对它们进行排序,同时以某种方式保持低内存占用率。
  • 如果您想在驱动器上找到最大的文件同时最小化 RAM 使用,您可以以花费时间和使用临时文件为代价来实现。尝试单独处理每个目录,找到目录中最大的文件,将其信息附加到文件(我会使用 CSV),然后读入文件并对其条目进行排序,取最大的 20 个。
  • 问题是 Sort-Object 需要在处理之前接收所有输出,您可以尝试在排序之前仅过滤感兴趣的属性(全名和长度),这会增加拍摄时间,但也会减少内存使用。

标签: powershell memory


【解决方案1】:

与您当前正在做的相比,这应该非常有效,基本上它利用 SortedSet<T> Class 和自定义 PowerShell Class 实现 IComparableIEquatable<T>。匿名函数内部的逻辑确保有序集合总是有一个最多 20 个元素(根据需要更改$sorted.Count -lt 20,具体取决于您想要的文件数量)因此内存使用率应该低得多。

class SimpleFile : System.IComparable, System.IEquatable[object] {
    [string] $FullName
    [Int64] $Length
    [double] $Gigabytes

    SimpleFile([IO.FileInfo] $File) {
        $this.FullName  = $File.FullName
        $this.Length    = $File.Length
        $this.Gigabytes = [Math]::Round($File.Length / 1Gb, 2)
    }

    [int] GetHashCode() {
        return $this.FullName.GetHashCode()
    }

    [int] CompareTo([object] $That) {
        if($diff = $this.Length.CompareTo($That.Length)) {
            return $diff
        }
        return 0
    }

    [bool] Equals([object] $That) {
        return $this.FullName -eq $That.FullName
    }
}

$result = Get-ChildItem C: -Recurse -File -EA 0 | & {
    begin {
        $sorted = [System.Collections.Generic.SortedSet[SimpleFile]]::new()
    }
    process {
        if($sorted.Count -lt 20) {
            $null = $sorted.Add($_)
            return
        }
        if($sorted.Min.Length -lt $_.Length) {
            $null = $sorted.Remove($sorted.Min)
            $null = $sorted.Add($_)
        }
    }
    end {
        $sorted.Reverse()
    }
}

【讨论】:

    猜你喜欢
    • 2014-05-11
    • 2011-02-27
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多