make原理

题目来源:字节

  1. make和new的区别

    1. new函数主要是为类型申请一片内存空间,返回执行内存的指针
    2. make函数能够分配并初始化类型所需的内存空间和结构,返回复合类型的本身。
    3. make函数仅支持 channelmapslice 三种类型,其他类型不可以使用使用make
    4. new函数在日常开发中使用是比较少的,可以被替代。
    5. make函数初始化slice会初始化零值,日常开发要注意这个问题。
  2. make函数底层实现
  1. func makeslice(et *_type, len, cap int) unsafe.Pointer {
  2. mem, overflow := math.MulUintptr(et.size, uintptr(cap))
  3. if overflow || mem > maxAlloc || len < 0 || len > cap {
  4. // NOTE: Produce a 'len out of range' error instead of a
  5. // 'cap out of range' error when someone does make([]T, bignumber).
  6. // 'cap out of range' is true too, but since the cap is only being
  7. // supplied implicitly, saying len is clearer.
  8. // See golang.org/issue/4085.
  9. mem, overflow := math.MulUintptr(et.size, uintptr(len))
  10. if overflow || mem > maxAlloc || len < 0 {
  11. panicmakeslicelen()
  12. }
  13. panicmakeslicecap()
  14. }
  15. return mallocgc(mem, et, true)
  16. }

函数功能:

  • 检查切片占用的内存空间是否溢出。
  • 调用mallocgc在堆上申请一片连续的内存。

检查内存空间这里是根据切片容量进行计算的,根据当前切片元素的大小与切片容量的乘积得出当前内存空间的大小,检查溢出的条件:

  • 内存空间大小溢出了
  • 申请的内存空间大于最大可分配的内存
  • 传入的len小于0cap的大小只小于`len