通过unsafe理解Go对象内存布局-《GO开发知识笔记》

admin 2025-11-04 00:56:21 编程 来源:ZONE.CI 全球网 0 阅读模式
  • 1.为什么gjson库会比内置库encoding/json快?(其他功能忽略,只说unsafe)
  • 2.如何理解unsafe 包之内存布局?

    1.为什么gjson库会比内置库encoding/json快?(其他功能忽略,只说unsafe)

    使用unsafe.Pointer破坏类型系统并读写任意内存,主要用于转换各种类型。image.png而笔者去看了一下encoding/json库,并没有发现用到unsafe。image.png看一组基准测试数据:image.pnggjson的getBytes方法源码,使用unsafe。image.pnghttps://github.com/tidwall/gjsoneasyjson的readme:image.pngunsafe是官方提议,不安全,要小心使用。除非用来管理内存布局使用。为什么可以做到这么快?因为使用unsafe包对内存直接进行读写, 而unsafe内置库是会绕开内存安全机制的。官方提供:unsafe package - unsafe - Go Packages

    2.如何理解unsafe 包之内存布局?

    需要了解的概念和unsafe API哦:

    • func Alignof(x ArbitraryType ) uintptr 对齐系数或者对齐倍数,每个字段在内存中的偏移量是对齐值的倍数
    • func Sizeof(x ArbitraryType ) uintptr内存大小,2^n。如果偏移量不够,则补齐。例如某struct结构体,字段A占1个字节、字段A4个字节,则大小为1+3+4=8。
    • 偏移量:计算机汇编语言,是指把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也称为“有效地址或偏移量”;
    • func Offsetof(x ArbitraryType ) uintptr 偏移量大小
    • 对齐值,此处golang的最大偏移量和内存大小有关,不同电脑有不同的值,我的是8.

    不同的struct字段编排,所占有的内存不同。代码如下:

    1. package main
    2. import (
    3. "fmt"
    4. "unsafe"
    5. )
    6. // 内存对齐影响struct的大小
    7. // struct的字段顺序影响struct的大小
    8. type user1 struct {
    9. b byte
    10. i int32
    11. j int64
    12. }
    13. type user2 struct {
    14. b byte
    15. j int64
    16. i int32
    17. }
    18. type user3 struct {
    19. i int32
    20. b byte
    21. j int64
    22. }
    23. type user4 struct {
    24. i int32
    25. j int64
    26. b byte
    27. }
    28. type user5 struct {
    29. j int64
    30. b byte
    31. i int32
    32. }
    33. type user6 struct {
    34. j int64
    35. i int32
    36. b byte
    37. }
    38. // 内存对齐影响struct的大小
    39. // struct的字段顺序影响struct的大小
    40. func main() {
    41. var u1 user1 // u1 size is 16
    42. var u2 user2 // u2 size is 24
    43. var u3 user3 // u3 size is 16
    44. var u4 user4 // u4 size is 24
    45. var u5 user5 // u5 size is 16
    46. var u6 user6 // u6 size is 16
    47. fmt.Println("u1 size is ", unsafe.Sizeof(u1))
    48. fmt.Println("u2 size is ", unsafe.Sizeof(u2))
    49. fmt.Println("u3 size is ", unsafe.Sizeof(u3))
    50. fmt.Println("u4 size is ", unsafe.Sizeof(u4))
    51. fmt.Println("u5 size is ", unsafe.Sizeof(u5))
    52. fmt.Println("u6 size is ", unsafe.Sizeof(u6))
    53. }

    image.png发现了,最后不同u1和u2内存大小不同。结论:1.内存对齐影响struct的大小(因为会补足到8的倍数)2.struct的字段顺序影响struct的大小(因为)所以有时候合理的字段顺序可以减少内存的开销

    以太坊cppgolang区别 编程

    以太坊cppgolang区别

    以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
    progolang 编程

    progolang

    Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
    golangn个发送者 编程

    golangn个发送者

    Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
    golang技能图谱 编程

    golang技能图谱

    从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
    评论:0   参与:  12