How to get memory size of variable?

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

Solution 1:

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.

Solution 2:

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

Solution 3:

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.

Solution 4:

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