You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言是否对切片操作的复用进行内存优化?

Go切片重复操作的内存占用与底层数组共享问题

首先明确结论:对同一个基础切片执行相同的切片操作时,两次得到的切片会共享同一个底层数组,不会创建独立的底层数组副本,内存占用在底层数组层面完全一致。

为什么会这样?

Go的切片本质是一个包含三个字段的结构体:

  • 指向底层数组的指针
  • 切片的长度(len)
  • 切片的容量(cap)

每次执行a[:4]这类切片操作时,会生成一个新的切片结构体,但这个结构体里的指针会直接指向原切片底层数组的对应起始位置(这里是原数组的第0个元素)。也就是说,底层数组完全复用,不会有新的内存分配,只是多了一个轻量的切片结构体(64位系统下仅占24字节:8字节指针+8字节len+8字节cap)。

验证方法(解决无法直接取切片地址的问题)

虽然直接对a[:4]取地址会报错(临时值不可寻址),但可以通过以下方式验证底层数组的共享性:

package main

import "fmt"

func main() {
    a := make([]int, 10)
    // 将切片操作结果赋值给变量
    s1 := a[:4]
    s2 := a[:4]
    
    // 打印底层数组的起始地址(通过切片第一个元素的地址)
    fmt.Printf("s1底层数组起始地址: %p\n", &s1[0])
    fmt.Printf("s2底层数组起始地址: %p\n", &s2[0])
    
    // 打印切片结构体自身的地址(两个结构体独立,但不影响底层数组)
    fmt.Printf("s1切片结构体地址: %p\n", &s1)
    fmt.Printf("s2切片结构体地址: %p\n", &s2)
}

运行这段代码会看到,s1和s2的底层数组起始地址完全相同,证明它们共享同一个底层数组;而切片结构体的地址不同,只是因为每次切片操作生成了新的结构体实例,但这种内存开销可以忽略不计。

回到你的代码场景

在你的代码中:

a := make([]int, 10)
log.Msgf("the subarray is: %v", a[:4])
return a[:4]

日志中的a[:4]和返回值的a[:4]是两个独立的切片结构体,但它们指向的是同一个底层数组,不会导致底层数组的内存被重复占用。编译器不会优化掉这两个切片结构体,但这种轻量级的内存开销在实际场景中几乎可以忽略。

内容的提问来源于stack exchange,提问作者Ivasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:03:15