简单的语句1..1GB
会填满内存,并且似乎挂在32 GiB的系统上。按Ctrl-C不执行任何操作。解释器内部发生了什么?如果让它运行足够长的时间,会产生正确的结果吗?
PS C:\> (Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory / 1MB
32629.1484375
PS C:\> $PSVersionTable.PSVersion.ToString()
7.3.4
PS C:\> 1..1GB
简单的语句1..1GB
会填满内存,并且似乎挂在32 GiB的系统上。按Ctrl-C不执行任何操作。解释器内部发生了什么?如果让它运行足够长的时间,会产生正确的结果吗?
PS C:\> (Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory / 1MB
32629.1484375
PS C:\> $PSVersionTable.PSVersion.ToString()
7.3.4
PS C:\> 1..1GB
1条答案
按热度按时间lymnna711#
..
,PowerShell的range运算符**:**懒地枚举 * 范围端点(包括)之间的值(在手头的情况下,
1
,2
,3
,...,1073741824
)(...)
中,将其分配给变量,或使其参与更大的表达式,PowerShell将为枚举值创建[object[]]
数组(使用(1..10).GetType()
进行验证)。考虑到值的绝对数量,用
1..1GB
枚举1GB
==1,073,741,824
(1 + billion)[1]值 * 非常慢 *-但 * 最终 * 在PowerShell (Core) 7+中返回(除非内存耗尽),而在 * Windows PowerShell * 中它会立即失败;正如zett42所指出的:$array = 1..1GB
失败并显示OutOfMemoryException
(Array dimensions exceeded supported range.
)。实际的限制甚至更低($array = 1..300MB
仍然失败,而$array = 1..200MB
成功)。[object[]]
数组的每个元素都是指针(引用)的大小,并且在64位进程中每个指针需要8个字节(用[IntPtr]::Size
验证),则实际限制接近2GB / 8
;256MB - 8
,准确地说。也就是说,$array = 1..(256MB - 8)
可以工作,但任何具有更多值的操作都将失败。2GB - 57
,即2,147,483,591
每个维度的元素([int]::MaxValue - 56
;使用[object[]]::new(2GB - 57).Count
进行验证-任何更高版本(如- 56
)使用Array dimensions exceeded supported range.
时均失败)4,294,967,182
==4GB - 114
)。然而,在PowerShell中很少使用这样的数组,并且更常用的 * jagged * 数组(其元素是其他数组的数组)不受此限制。请注意,**如果您使用范围操作作为 * 管道输入 *,***而不将其包含在
(...)
* 中,则懒惰枚举行为将变得明显-*不创建数组 ,并且枚举值是 * 流式传输:如果您使用此表单:
[int]
(System.Int32
),这将您限制为[int]::MaxValue + 1
,即2GB
范围内的值;即以1
为起点,最高终点为[int]::MaxValue
((2GB-1)
)。请注意,
..
在PowerShell运算符中不常见**,因为它结合了非管道和管道行为:* in isolation *-当您既不捕获它也不将它发送到另一个命令时-它在[object[]]
数组中被 * 隐式地 * 捕获,并且只有在它创建之后,结果数组的to-host(to-console)输出才开始;也就是说,流 * 不会 * 发生,除非您将操作用作 * 显式 * 管道的输入。1..50MB
和1..50MB | Write-Output
的输出行为:前者在输出开始之前产生明显的延迟,这是由于首先创建(大)数组,而后者 * 流式传输 * 其值,因此立即开始产生输出。*情境 * 流行为 * 也 * 在
foreach
和switch
语句的上下文中出现:..
在那里也表现出 * 流 * 行为:[1]正如mclayton所指出的,
GB
后缀是 *(二进制)千兆字节乘数 *(相当于[Math]::Pow(2, 30)
==1,073,741,824
的因子),PowerShell支持的数字 * 文字 * 中的几个二进制乘数之一。