如何获取变量的内存大小?

时间:2014-11-17 15:13:56

标签: memory-management go runtime

有人知道如何获取变量(intstring[]struct等)的内存大小并打印出来吗?有可能吗?

var i int = 1
//I want to get something like this:
fmt.Println("Size of i is: %?", i)
//Also, it would be nice if I could store the value into a string

5 个答案:

答案 0 :(得分:33)

您可以使用unsafe.Sizeof功能。 它返回以字节为单位的大小,由传递给它的值占用。 这是a working example

package main

import "fmt"
import "unsafe"

func main() {
    a := int(123)
    b := int64(123)
    c := "foo"
    d := struct {
        FieldA float32
        FieldB string
    }{0, "bar"}

    fmt.Printf("a: %T, %d\n", a, unsafe.Sizeof(a))
    fmt.Printf("b: %T, %d\n", b, unsafe.Sizeof(b))
    fmt.Printf("c: %T, %d\n", c, unsafe.Sizeof(c))
    fmt.Printf("d: %T, %d\n", d, unsafe.Sizeof(d))
}

请注意,某些平台明确禁止使用不安全的,因为它是......好吧,不安全。这曾经包括AppEngine。不确定今天是否仍然如此,但我想是这样。

正如@Timur Fayzrakhmanov所说,reflect.TypeOf(variable).Size()会给你相同的信息。对于reflect包,与unsafe包的限制相同。即:某些平台可能不允许使用它。

答案 1 :(得分:11)

您可以使用unsafe.Sizeof()reflect.Type.Size()

执行此操作

答案 2 :(得分:4)

可以使用unsafe.Sizeof(a)确定变量的大小。对于给定类型(即intint64stringstruct等),结果将保持不变,无论其值如何。但是,对于类型string,您可能对变量引用的字符串的大小感兴趣,这是通过对给定字符串使用len(a)函数来确定的。以下代码段说明了string类型变量的大小始终为8,但变量引用的字符串长度可能会有所不同:

package main

import "fmt"
import "unsafe"

func main() {
    s1 := "foo"
    s2 := "foobar"

    fmt.Printf("s1 size: %T, %d\n", s1, unsafe.Sizeof(s1))
    fmt.Printf("s2 size: %T, %d\n", s2, unsafe.Sizeof(s2))
    fmt.Printf("s1 len: %T, %d\n", s1, len(s1))
    fmt.Printf("s2 len: %T, %d\n", s2, len(s2))
}

输出:

s1 size: string, 8
s2 size: string, 8
s1 len: string, 3
s2 len: string, 6

问题的最后一部分是将长度(即int值)分配给string。这可以通过s := strconv.Itoa(i)完成,其中iint变量,并且该函数返回的string已分配给s

注意:转换器函数的名称是Itoa,可能是整数到ASCII的简写形式。大多数Golang程序员可能会将函数名称误读为Iota

答案 3 :(得分:1)

我编写了一个程序包,用于计算运行时变量消耗的实际内存大小:https://github.com/DmitriyVTitov/size 它具有单一功能,因此基本用法是:

fmt.Println(size.Of(varName))

答案 4 :(得分:0)

unsafe.Sizeof()是正确的解决方案。

var i int
var u uint
var up uintptr


fmt.Printf("i Type:%T Size:%d\n", i, unsafe.Sizeof(i))
fmt.Printf("u Type:%T Size:%d\n", u, unsafe.Sizeof(u))
fmt.Printf("up Type:%T Size:%d\n", up, unsafe.Sizeof(up))

int,uint和uintptr类型在32位系统上通常为32位宽,在64位系统上为64位宽。当你需要一个整数值时,你应该使用int,除非你有特定的理由使用大小或无符号整数类型。