美文网首页
golang struct{} 2022-02-15

golang struct{} 2022-02-15

作者: 9_SooHyun | 来源:发表于2022-02-19 16:34 被阅读0次

golang 空struct内存占用为0,且所有的空struct都引用的是同一地址

func TestEmptyStruct(t *testing.T) {
    type emptyStruct struct{}
    type emptyInside struct {
        emptyStruct
    }
    type personStruct struct {
        E1 emptyStruct
        A  struct {
            Age int
        }
        E2 emptyStruct
        S  struct {
            Sex string
        }
        E3 struct {
        }
    }
    a := struct{}{}
    b := emptyStruct{}
    eInside := emptyInside{emptyStruct: emptyStruct{}}
    fmt.Printf("%p\n", &a)
    fmt.Printf("%p\n", &b)
    fmt.Printf("%p\n", &eInside)
    fmt.Println("size of a is ", unsafe.Sizeof(a), " size of b is ", unsafe.Sizeof(b), " size of eInside is ", unsafe.Sizeof(eInside))
    // 0x2c2bb60
    // 0x2c2bb60
    // 0x2c2bb60  -> 空结构体(包括不断嵌套但仍然无任何内置字段的空结构体)的变量的内存地址都是一样的,所有空struct都是引用全局变量zerobase的地址
    // size of a is  0  size of b is  0  size of eInside is  0

    c := personStruct{}
    fmt.Printf("%s, %p\n", "c", &c)
    fmt.Printf("%s, %p\n", "c.E1", &c.E1)
    fmt.Printf("%s, %p\n", "c.A", &c.A)
    fmt.Printf("%s, %p\n", "c.E2", &c.E2)
    fmt.Printf("%s, %p\n", "c.S", &c.S)
    fmt.Printf("%s, %p\n", "c.E3", &c.E3)
    // c, 0xc00016b8e0
    // c.E1, 0xc00016b8e0
    // c.A, 0xc00016b8e0 -> c, c.E1, c.A地址相同,空结构体不占任何内存空间
    // c.E2, 0xc00016b8e8 -> e8 - e0 = 8. golang int类型在32位系统4字节 64位系统8字节
    // c.S, 0xc00016b8e8
    // c.E3, 0xc00016b8f8 -> f8 - e8 = 16

    // golang string数据类型占用16字节空间,
    // 前8字节是一个指针,指向字符串值的地址,
    // 后八个字节是一个整数,标识字符串的长度;
    // 注意go语言的字符串内部并不以'\0'作为结尾,而是通过一个长度域来表示字符串的长度
}

go编译器在编译期间,识别到 struct {} 这种特殊类型的内存分配,会统统分配出 runtime.zerobase 的地址出去,代码逻辑是在 mallocgc 函数里面:
代码如下:

func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
    // 分配 size 为 0 的结构体,把全局变量 zerobase 的地址给出去即可;
    if size == 0 {
        return unsafe.Pointer(&zerobase)
    }
    // ...

相关文章

网友评论

      本文标题:golang struct{} 2022-02-15

      本文链接:https://www.haomeiwen.com/subject/wlrllrtx.html