Go 语言中 append 导致内存不足

首发于:https://studygolang.com/articles/12929

这是一篇简短的笔记,关于你或许会遇上的 Go 语言的内存不足的问题。

如你所知,Go 语言的 slice 很强大且使用简单。通过 Go 语言的内置函数,它可以解决我们许多问题。

但是今天,我更多想讲述的是 slice 与它的内存。

首先,创建 slice 最简单的方式是:

当你创建一个 slice, 将会定义三个重要的信息,包含这个数组的指针 pointer,堆栈的已使用长度 length ,以及容量 capacity (堆栈的最大长度)

长度是切片引用的元素的数量

容量是底层数组中元素的数量(从切片指针引用的元素开始)

于是,当你使用我给出的以上方式创建 slices ,长度和容量将是最小的。

我们转下一个话题,Go 语言的 append 函数。

这个内置函数 append 把元素追加到 slice 的末尾,如果有足够的容量,就直接在末尾的内存加入这个新元素。如果没有足够的空间,则新分配一个新的基础的数组,追加更新的 slice 。

问题在于我们经常以为 append 会追加一个新的元素到 slice 的末尾,而忘记了如果没有足够的预留容量,这个操作会导致在新的内存上重新分配一个新的 slice 。

使用这个最简单的方式来创建 slice ,容量(capacity)总是与切片中的当前元素相匹配。不幸的是,有些源代码里是将 append 函数放到循环或嵌套循环中执行,快速的循环没什么问题,但是更大的循环,可能会引发问题,它会急速消耗内存。

你可以想象,每一个循环都会分配一个拥有新的容量的新内存,并且它还没来得及释放就得内存,我们就会看到以下错误

内存不足

Go 内置的代码在给 slice 分配内存空间时会预留更多的容量(capacity),这使得 append 不会因为容量不足而分配新的内存。

总而言之,我写这一篇文章,是希望我们在编程时,不妨思考多一些关于内存如何操作的问题。

希望这文章能帮到您 :)

via: https://blog.siliconstraits.com/out-of-memory-with-append-in-golang-956e7eb2c70e

作者:Thuc Le

译者:lightfish-zhang

校对:polaris1119

本文由 GCTT 原创编译,Go 中文网 荣誉推出

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181206B0TMAL00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券