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

huangapple go评论75阅读模式
英文:

How to get memory size of variable?

问题

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

var i int = 1
// 我想要得到类似这样的结果:
fmt.Println("i的大小为:%?", i)
// 另外,如果我能将这个值存储到一个字符串中就更好了
英文:

Does anybody know how to get memory size of the variable (int, string, []struct, etc) and print it? Is it possible?

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

答案1

得分: 76

你可以使用unsafe.Sizeof函数来实现这个功能。它会返回你传入的值所占用的字节数。
这里有一个可运行的示例

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

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

正如@Timur Fayzrakhmanov所指出的,reflect.TypeOf(variable).Size()可以给你相同的信息。对于reflect包,与unsafe包一样,同样存在一些平台可能不允许使用的限制。

英文:

You can use the unsafe.Sizeof function for this.
It returns the size in bytes, occupied by the value you pass into it.
Here's 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))
}

Take note that some platforms explicitly disallow the use of unsafe, because it is.. well, unsafe. This used to include AppEngine. Not sure if that is still the case today, but I imagine so.

As @Timur Fayzrakhmanov notes, reflect.TypeOf(variable).Size() will give you the same information. For the reflect package, the same restriction goes as for the unsafe package. I.e.: some platforms may not allow its use.

答案2

得分: 19

你可以使用unsafe.Sizeof()reflect.Type.Size()来完成。

英文:

You can do it with either unsafe.Sizeof(), or reflect.Type.Size()

答案3

得分: 7

变量的大小可以通过使用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)来实现,其中i是一个int变量,函数返回的string被赋给s

注意:转换函数的名称是Itoa,可能是Integer to ASCII的缩写形式。大多数Golang程序员可能会错误地将函数名读作Iota

英文:

The size of a variable can be determined by using unsafe.Sizeof(a). The result will remain the same for a given type (i.e. int, int64, string, struct etc), irrespective of the value it holds. However, for type string, you may be interested in the size of the string that the variable references, and this is determined by using len(a) function on a given string. The following snippet illustrates that size of a variable of type string is always 8 but the length of a string that a variable references can vary:

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

Output:

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

The last part of your question is about assigning the length (i.e. an int value) to a string. This can be done by s := strconv.Itoa(i) where i is an int variable and the string returned by the function is assigned to s.

Note: the name of the converter function is Itoa, possibly a short form for Integer to ASCII. Most Golang programmers are likely to misread the function name as Iota.

答案4

得分: 5

我已经写了一个包,可以在运行时计算变量实际占用的内存大小:https://github.com/DmitriyVTitov/size
它只有一个函数,所以基本用法是:

fmt.Println(size.Of(varName))

英文:

I've written a package which calculates the actual memory size consumed by variable at runtime: https://github.com/DmitriyVTitov/size
It has single function, so basic usage is:

fmt.Println(size.Of(varName))

答案5

得分: 0

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

var i int
var u uint
var up uintptr


fmt.Printf("i 类型:%T 大小:%d\n", i, unsafe.Sizeof(i))
fmt.Printf("u 类型:%T 大小:%d\n", u, unsafe.Sizeof(u))
fmt.Printf("up 类型:%T 大小:%d\n", up, unsafe.Sizeof(up))

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

英文:

unsafe.Sizeof() is the correct solution.

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

The int, uint, and uintptr types are usually 32 bits wide on 32-bit systems and 64 bits wide on 64-bit systems. When you need an integer value you should use int unless you have a specific reason to use a sized or unsigned integer type.

huangapple
  • 本文由 发表于 2014年11月17日 23:13:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/26975738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定