【问题标题】:Maximum length of a slice in GoGo中切片的最大长度
【发布时间】:2015-02-23 05:04:27
【问题描述】:

我在 4Gb 机器的 64 位 linux 操作系统中运行以下代码:

package main

import (
    "fmt"
    "math"
)

func main() {
    r := make([]bool, math.MaxInt32)

    fmt.Println("Size: ", len(r))
}

当我运行它时,我得到:

Size: 2147483647

如果我将math.MaxInt32 更改为math.MaxUint32,我会得到:

fatal error: runtime: out of memory

切片大小为math.MaxUint32 时内存不足,这是我的预期,但当我尝试使用math.MaxInt64 时,我得到:

panic: runtime error: makeslice: len out of range

所以显然我无法创建大小为 math.MaxInt64 的切片,这让我们想到了一个问题:如果内存不是问题,那么我在 Go 中无法创建的最大切片是什么?

我记得,在 Java 中,原始数组索引是使用 int 类型管理的,所以原始数组的最大大小是 int 的最大值,如果您尝试使用 long它会引发异常(据我所知),Go 也一样吗? Go 中的切片索引是否绑定到一种特定类型?

编辑:

我使用struct{} 而不是bool 运行测试并分配math.MaxInt64 元素。一切都按预期进行,并打印:

Size: 9223372036854775807

那么,另一个问题,为什么在看起来错误相同(内存不足)时会出现两条不同的错误消息?

每个错误弹出的条件是什么?

【问题讨论】:

  • 看来这是错误信息不明确的问题,仅此而已... :)

标签: go slice


【解决方案1】:

根据文档,The elements can be addressed by integer indices 0 through len(s)-1。这意味着切片的最大容量是目标构建上默认整数的大小。

编辑:从查看源代码来看,似乎有一个安全检查来确保这个切片大小是完全可能的:

func makeslice(t *slicetype, len64 int64, cap64 int64) sliceStruct {
    // NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
    // but it produces a 'len out of range' error instead of a 'cap out of range' error
    // when someone does make([]T, bignumber). 'cap out of range' is true too,
    // but since the cap is only being supplied implicitly, saying len is clearer.
    // See issue 4085.
    len := int(len64)
    if len64 < 0 || int64(len) != len64 || t.elem.size > 0 && uintptr(len) > maxmem/uintptr(t.elem.size) {
        panic(errorString("makeslice: len out of range"))
    }

所以在这种情况下,它看起来像uintptr(len) &gt; maxmem/uintptr(t.elem.size),所以我们不允许进行这种大小的分配。

但是,当我分配不占用内存的struct{} 时,这个大小是允许的:

func main(){
    r := make([]struct{}, math.MaxInt64)
    fmt.Println(len(r))
}
// prints 9223372036854775807

【讨论】:

  • 我确定我运行的是 64 位 Go,如果我这样做 go version 它会打印出 go version go1.4 linux/amd64
  • @SimonOroño go env 为 GOARCH 打印什么?
  • @SimonOroño 我看过 Go 的源代码,我想我知道这个问题。更新我的答案。
  • amd64.我使用 struct{} 运行测试并且不得不更新问题。请检查一下:-) @Not_a_Golfer
  • 好吧,如果进行了检查,那么我如何使用boolmath.MaxUint32 获得fatal error: runtime: out of memory
猜你喜欢
  • 1970-01-01
  • 2016-02-24
  • 2018-02-15
  • 2021-12-23
  • 2015-05-07
  • 1970-01-01
  • 2017-10-20
  • 2016-08-09
  • 1970-01-01
相关资源
最近更新 更多