Go 陷阱之切片占用过多内存

概述 #

切片的底层数据结构是数组,同样,切片的子切片会引用同样的数组。如果切片不主动不释放的话,那么底层的数组就会一直占用着内存

切片返回值占用了整个数组 #

示例代码只是为了演示,没有任何实际意义。

错误的做法 #

package main

import "fmt"

func getFirstThreeNumber() []byte {
	res := make([]byte, 1000)
	fmt.Println(len(res), cap(res))
	return res[:3]
}

func main() {
	res := getFirstThreeNumber()
	fmt.Println(len(res), cap(res))
}

// $ go run main.go
// 输出如下
/**
  1000 1000
  3 1000
*/

从输出结果中可以看到,即使函数已经返回切片,但是切片底层的数组一直被占用着,没有释放掉,浪费了很多内存。

正确的做法 #

分配一个合适大小的切片作为函数的返回值,这样函数返回后,切片底层的数组就会被释放掉。

package main

import "fmt"

func getFirstThreeNumber() []byte {
	data := make([]byte, 1000)
	fmt.Println(len(data), cap(data))

	res := make([]byte, 3)
	copy(res, data[:3])
	return res
}

func main() {
	res := getFirstThreeNumber()
	fmt.Println(len(res), cap(res))
}

// $ go run main.go
// 输出如下
/**
  1000 1000
  3 3
*/

从输出结果中可以看到, 函数返回后,切片底层的数组已经被释放。

转载申请

本作品采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,商业转载请联系作者获得授权。

© 蛮荆 | 陕公网安备 61011302001681 号 | 陕ICP备2023004378号-1 | Rendered by Hugo