golang 分配内存主要有内置函数new和make,今天我们来探究一下make有哪些玩法。

map只能为slice, map, channel分配内存,并返回一个初始化的值。首先来看下make有以下三种不同的用法:

1. make(map[string]string)

2. make([]int, 2)

3. make([]int, 2, 4)

1. 第一种用法,即缺少长度的参数,只传类型,这种用法只能用在类型为map或chan的场景,例如make([]int)是会报错的。这样返回的空间长度都是默认为0的。

2. 第二种用法,指定了长度,例如make([]int, 2)返回的是一个长度为2的slice

3. 第三种用法,第二参数指定的是切片的长度,第三个参数是用来指定预留的空间长度,例如a := make([]int, 2, 4), 这里值得注意的是返回的切片a的总长度是4,预留的意思并不是另外多出来4的长度,其实是包含了前面2个已经切片的个数的。所以举个例子当你这样用的时候 a := make([]int, 4, 2),就会报语法错误。

因此,当我们为slice分配内存的时候,应当尽量预估到slice可能的最大长度,通过给make传第三个参数的方式来给slice预留好内存空间,这样可以避免二次分配内存带来的开销,大大提高程序的性能。

而事实上,我们其实是很难预估切片的可能的最大长度的,这种情况下,当我们调用append为slice追加元素时,golang为了尽可能的减少二次分配内存,并不是每一次都只增加一个单位的内存空间,而且遵循这样一种扩容机制:

当有预留的未使用的空间时,直接对未使用的空间进行切片追加,当预留的空间全部使用完毕的时候,扩容的空间将会是当前的slice长度的一倍,例如当前slice的长度为4,进行一次append操作之后,cap(a)返回的长度将会是8.来看下面这段演示代码:

package mainimport ("fmt"
)func main() {a :=  make([]int, 0)n := 20for i := 0; i < n; i++ {a = append(a, 1)fmt.Printf("len=%d cap=%d\n", len(a), cap(a))}
}Output:
len=1 cap=1  // 第一次扩容
len=2 cap=2 // 第二次扩容
len=3 cap=4 // 第三次扩容
len=4 cap=4
len=5 cap=8 // 第四次扩容
len=6 cap=8
len=7 cap=8
len=8 cap=8
len=9 cap=16 // 第五次扩容
len=10 cap=16
len=11 cap=16
len=12 cap=16
len=13 cap=16
len=14 cap=16
len=15 cap=16
len=16 cap=16
len=17 cap=32 // 第六次扩容
len=18 cap=32
len=19 cap=32
len=20 cap=32

以上测试结果表明,每次扩容后,内存空间长度会变为原来的两倍。

好奇的我想试一下,如果一直这样扩展下去的话,理论上会呈指数扩展,然而事实真的会这样吗,我继续进行append操作,后续的输出是这样的:

0 0
1 1
2 2
4 4
8 8
16 16
32 32
64 64
128 128
256 256
512 512
1024 1024
1312 1312    // 288
1696 1696    // 384
2208 2208    // 512
3072 3072    // 864
4096 4096    // 1024
5120 5120    // 1024
7168 7168    // 2048
9216 9216    // 2048

上面的输出忽略掉了中间没有扩容的情况。可以看到,前11次扩容确实是每次扩展一倍的长度,不过第12次扩容,明显没有按照预期扩展到2048。

Golang make多种使用方法详解相关推荐

  1. golang 解析php序列化,golang实现php里的serialize()和unserialize()序列和反序列方法详解...

    Golang 实现 PHP里的 serialize() . unserialize() 安装 go get -u github.com/techleeone/gophp/serialize 用法 pa ...

  2. python怎么读文件内容-Python读取文件内容为字符串的方法(多种方法详解)

    以下笔记是我在 xue.cn 学习群之数据分析小组所整理分享的心得.相关背景是:我选择中文词频统计案例作为考察大家python基础功掌握程度. 以小见大,下面是2个小技能的具体实战: 如何灵活地处理文 ...

  3. python清空集合_python集合删除多种方法详解

    这篇文章主要介绍了python集合删除多种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 删除指定的元素 A={'a','c','b','d ...

  4. python语言格式化输出_Python format()格式化输出方法详解

    原标题:Python format()格式化输出方法详解 format() 方法的语法格式如下: str.format(args) 此方法中,str 用于指定字符串的显示样式:args 用于指定要进行 ...

  5. php中读取大文件实现方法详解

    php中读取大文件实现方法详解 来源:   时间:2013-09-05 19:27:01   阅读数:6186 分享到:0 [导读] 本文章来给各位同学介绍php中读取大文件实现方法详解吧,有需要了解 ...

  6. 使用Java操作文本文件的方法详解

    使用Java操作文本文件的方法详解 摘要: 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而 ...

  7. Vue通信、传值的多种方式,详解

    Vue通信.传值的多种方式,详解 转自:https://blog.csdn.net/qq_35430000/article/details/79291287 一.通过路由带参数进行传值 ①两个组件 A ...

  8. [转]VB中资源文件.res的使用方法详解

    在几乎所有的Windows应用程序中都拥有资源文件,这些文件定义使用应用程序将要显示很多的用户界面元素,以及提供程序所需要的各种类型数据的存储场所.资源文件在VC应用程序中应用十分广泛,在VB应用中却 ...

  9. python怎么横着输出_对python3中, print横向输出的方法详解

    对python3中, print横向输出的方法详解 Python 2 : print打印的时候,如果结尾有逗号,打出来时候不会换行.但是在python3里面就不行了. Python3: 3.0的pri ...

最新文章

  1. 畅通工程//最小生成树prim
  2. 《R in Action》读书笔记(1)
  3. selenium 无法定位打开a链接_测试干货 :Selenium8种元素定位法
  4. 下载并导出数据到execl中
  5. 如何在Node.js(Javascript)中等待,我需要暂停一段时间?
  6. Ubantu16.04安装显卡驱动遇到的坑
  7. SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装
  8. 第 6-7 课:Java 分布式框架面试题合集
  9. 修改Typora的快捷键【markdown软件】
  10. 用智能墨水打造超灵敏传感器 “写”到哪里感知就到哪里...
  11. 设计模式之十一:创建模式(Builder Pattern)
  12. 矩阵维度必须一致是什么意思_糖化肌肤是什么意思?抗糖养肤你必须知道这些...
  13. 中建信息的新分销主义
  14. android改变textview文字,如何在Android TextView中更改文本
  15. 逻辑运算 神经网络_使用神经网络实现逻辑门(第2部分)
  16. 梦幻家园前37关(iPad)
  17. ggplot2——双坐标轴?
  18. ArcGIS小知识(八)——坡降、流动方向、剖面线、弯曲系数、河系密度、补给长度比
  19. mysql配置报错thread_MySQL错误Forcing close of thread的两种解决方法
  20. 用echarts写潮汐表,并处理后端传来的数据为潮汐表接口的数据

热门文章

  1. 有用的vscode快捷键大全+自定义快捷键
  2. js笛卡尔乘积算法实现sku
  3. Joint Event and Temporal Relation Extraction with Shared Representations and Structured Prediction
  4. 《洛杉矶之战》影评:真人版的合金弹头
  5. IIS PHP web.config设置去掉index.php
  6. Python 快速实现栅格地图
  7. Java文件是怎么编译成Class文件的
  8. 融资融券业务的要求有哪些?
  9. dos命令行连接oracle数据库
  10. 《与时间做朋友》读书笔记