2014-12-25 18 views
7

Tôi có đoạn code sau chạy trong một hệ điều hành Linux 64-bit trong một máy 4Gb:Chiều dài tối đa của một lát tại Gò

package main 

import (
    "fmt" 
    "math" 
) 

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

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

Khi tôi chạy này, tôi nhận được:

Size: 2147483647 

Nếu tôi thay đổi math.MaxInt32 cho math.MaxUint32 tôi nhận được:

fatal error: runtime: out of memory 

với kích thước lát math.MaxUint32 tôi chạy ra khỏi bộ nhớ, tôi đã mong rằng, nhưng khi tôi thử sử dụng math.MaxInt64 tôi nhận được:

panic: runtime error: makeslice: len out of range 

Vì vậy aparently Tôi không thể tạo ra một lát với kích thước của math.MaxInt64, mà đưa chúng ta đến câu hỏi của tôi: Nếu nhớ không phải là một vấn đề, slice lớn nhất mà tôi không thể tạo trong Go là gì?

Tôi nhớ rằng, trong Java, chỉ số mảng liệu được quản lý bằng các loại int, vì vậy kích thước tối đa của một mảng nguyên là giá trị tối đa của một int, nếu bạn cố gắng làm điều đó với long nó sẽ nâng cao một ngoại lệ (theo như tôi nhớ), nó có giống với Go không? là chỉ mục slice trong Go bị ràng buộc với một loại cụ thể?

EDIT:

tôi chạy thử nghiệm sử dụng struct{} thay vì bool và phân bổ math.MaxInt64 yếu tố. Tất cả mọi thứ đã đi như mong đợi, và in:

Size: 9223372036854775807 

Vì vậy, một câu hỏi khác, tại sao có hai thông báo lỗi khác nhau khi có vẻ như rằng lỗi là như nhau (không đủ bộ nhớ)?

Các điều kiện cho từng lỗi xuất hiện là gì?

+0

Vì vậy, có vẻ như đó là một vấn đề của sự nhập nhằng thông báo lỗi, không có gì hơn ... :) –

Trả lời

10

Theo tài liệu, The elements can be addressed by integer indices 0 through len(s)-1. Điều này có nghĩa là dung lượng tối đa cho một lát là kích thước của số nguyên mặc định trên bản dựng đích.

EDIT: Từ cách nhìn vào mã nguồn, dường như có một kiểm tra an toàn để đảm bảo kích thước này lát là ở tất cả các khả năng:

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")) 
    } 

Vì vậy, trong trường hợp này, có vẻ như uintptr(len) > maxmem/uintptr(t.elem.size) nên chúng tôi không được phép thực hiện quy mô phân bổ này.

Tuy nhiên khi tôi phân bổ struct{} mà mất không nhớ, kích thước này được phép:

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

Tôi chắc chắn rằng Tôi chạy 64 bit Go, nếu tôi làm 'đi phiên bản' nó in' đi phiên bản go1.4 linux/amd64' –

+0

@ SimonOroño những gì hiện 'đi env' in cho GOARCH? –

+0

@ SimonOroño Tôi đã xem mã nguồn của Go và tôi nghĩ rằng tôi biết vấn đề. Cập nhật câu trả lời của tôi. –

Các vấn đề liên quan