Go的垃圾回收

示例代码

go 复制代码
// package main

// import (
// 	"fmt"
// 	"runtime" // 只保留需要的包,移除 unused 的 "unsafe"
// )

// func main() {
// 	// 1. 定义一个 runtime.MemStats 结构体,用于接收内存统计数据
// 	var m runtime.MemStats

// 	// 2. 第一次读取内存状态(调用时传入 &m 指针)
// 	runtime.ReadMemStats(&m)
// 	fmt.Printf("GC 前: 分配的内存 = %d 字节\n", m.Alloc)

// 	// 手动触发一次 GC(可选,用于测试)
// 	runtime.GC()

// 	// 3. 第二次读取内存状态
// 	runtime.ReadMemStats(&m)
// 	fmt.Printf("GC 后: 分配的内存 = %d 字节\n", m.Alloc)
// }

优化GC的一些注意事项

拿字符串举例子

go 复制代码
package main

import (
	"fmt"
	"runtime"
)

func main() {
	var m runtime.MemStats // 用于接收内存统计的结构体

	// 创建一个超长字符串(底层是一个大字节数组)
	long := make([]byte, 1000000)
	for i := range long {
		long[i] = 'a'
	}
	s := string(long) // s 引用底层的大字节数组

	// 方法1:直接切片(共享底层大数组)
	short := s[len(s)-3:] // short 是 s 的切片,仍引用原大数组
	fmt.Println("short:", short)

	// 记录 GC 前的堆内存使用
	runtime.ReadMemStats(&m)
	fmt.Println("Memory Before GC:", m.HeapInuse, "bytes")

	// 触发 GC
	runtime.GC()

	// 记录 GC 后的堆内存使用(此时大数组可能未被回收)
	runtime.ReadMemStats(&m)
	fmt.Println("Memory After GC:", m.HeapInuse, "bytes")

	// 方法2:复制切片(创建新的小内存块)
	shortCopy := string([]byte(short)) // 将 short 转为字节数组再转字符串,创建新内存
	fmt.Println("shortCopy:", shortCopy)

	// 再次触发 GC
	runtime.GC()

	// 记录复制后的 GC 内存使用(原大数组可被回收)
	runtime.ReadMemStats(&m)
	fmt.Println("Memory After Copy + GC:", m.HeapInuse, "bytes")
}
  • 每个人的情况不一样

关键原理:切片的 "底层数组引用" 对 GC 的影响

  • 方法 1(直接切片 short := slen(s)-3:)

Go 中的字符串切片本质是 "原字符串的视图",它会共享底层的大字节数组(即使只取最后 3 个字符)。此时,虽然你只需要 3 个字符,但由于

short 仍引用着原大数组,GC 会认为 "大数组仍在被使用",因此不会回收这个大数组,导致内存占用居高不下。

  • 方法 2(复制切片 shortCopy := string(\[\]byte(short)))

通过 \[\]byte(short) 将切片转为字节数组(会复制出一个仅包含 3 个字符的新数组),再转为字符串shortCopy。此时,shortCopy 引用的是新的小内存块,原大数组不再被任何变量引用,GC会在下次回收时释放大数组的内存,从而显著降低内存占用。 总结 直接切片会导致"底层大内存块被长期引用而无法回收",可能造成内存浪费(尤其是处理大字符串 / 切片时)。 若只需使用切片的一小部分,通过 "复制"创建新的小内存块(如 string(\[\]byte(short))),可以让原大内存块被 GC 回收,从而优化内存使用。

相关推荐
樱花落木兰10 小时前
Redis 消息队列的可靠性演进:从 List、Pub/Sub 到 Stream 消费者组,以及 8.x 版本改变了什么
java·开发语言·经验分享·redis·分布式·python·软件工程
学长毕设10 小时前
基于SpringBoot的文具商城在线零售系统-附源码
spring boot·后端·零售
外收内放10 小时前
ENSP学习记录(6)
开发语言·学习·php
dialect_10 小时前
CODEFORCES ROUND 1127 DIV2
开发语言·c++·算法
盛世宏博北京10 小时前
档案库房恒温恒湿消毒净化一体机与3D可视化平台联动调试笔记
开发语言·php·温湿度·档案室
乐橙开放平台10 小时前
离岗检测怎么实现?通过客流相机或 AI 摄像头识别岗位区域无人状态,再推送告警消息
人工智能·笔记·后端·数码相机·物联网·自动化·音视频
小徐不徐说19 小时前
序列化与反序列化:把 C++ 对象可靠地保存下来
开发语言·数据库·c++·php
ZhengEnCi19 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
ragnwang19 小时前
Notes: Python pybind11 import C++ module
开发语言·c++·python
王中阳Go19 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型