当前位置: 首页 > backend >正文

Go语言中内存释放 ≠ 资源释放

// QueryUserFileMetas : 批量获取用户文件信息
func QueryUserFileMetas(username string, limit int) ([]UserFile, error) {stmt, err := mydb.DBConn().Prepare("select file_sha1,file_name,file_size,upload_at," +"last_update from tbl_user_file where user_name=? limit ?")if err != nil {return nil, err}defer stmt.Close()rows, err := stmt.Query(username, limit)if err != nil {return nil, err}var userFiles []UserFilefor rows.Next() {ufile := UserFile{}err = rows.Scan(&ufile.FileHash, &ufile.FileName, &ufile.FileSize,&ufile.UploadAt, &ufile.LastUpdated)if err != nil {fmt.Println(err.Error())break}userFiles = append(userFiles, ufile)}return userFiles, nil
}

这里的stmt需要手动回收,rows需要吗?

对象是否需要手动关闭为什么
stmt(预处理语句)需要占用数据库连接资源,必须关闭释放资源
rows(查询结果集)也需要持有数据库游标或连接,必须关闭释放资源

🔍 原因详解
🔹1. stmt.Close()
stmt 是通过 Prepare() 创建的预编译语句句柄。
它通常会绑定数据库连接资源,即使查询结束也不会自动释放。
不关闭会导致连接池资源泄漏,最终使数据库拒绝新的连接。

🔹2. rows.Close()
rows 是执行查询后返回的结果集,底层其实是一个游标。
也持有数据库连接,直到你显式地关闭或完全遍历完所有行。
如果不 Close():
连接不会释放给连接池(可能一直挂起)
资源泄漏:数据库连接数会越来越多,直到超出限制

✅ 总结
stmt.Close() 和 rows.Close() 都必须显式调用,通常用 defer 来管理。
否则会引起连接池资源耗尽、数据库连接泄漏等问题。
Go 的数据库接口(database/sql)设计得很灵活,但需要你手动管理生命周期。

疑问?为什么不会随着函数的调用结束被内存自动回收了呢?

🧠 背后原理:内存释放 ≠ 资源释放

Go 的垃圾回收器(GC)能做什么?
GC 只能自动清理内存对象(如你创建的结构体、切片、字符串等),前提是这些对象不再被引用。
GC 无法自动释放 “非内存资源”,比如:

  1. 网络连接(TCP socket).
  2. 数据库连接
  3. 文件句柄
  4. goroutine(除非主动退出)
  5. 系统级游标、IO句柄等

✅ Go GC 是“内存管理器”,而非“资源管理器”。

🔍 对比:内存 vs 非内存资源

类型例子GC 能自动释放?需要手动释放?
内存对象[]byte, string, map✅ 是❌ 否
数据库连接rows, stmt, tx❌ 否✅ 是
网络连接net.Conn❌ 否✅ 是
文件句柄os.File❌ 否✅ 是

Go 的垃圾回收器只会自动释放内存,但不会自动关闭文件、数据库连接等 “非内存资源”。这些资源你必须手动关闭。

http://www.xdnf.cn/news/8353.html

相关文章:

  • 【JVM 03-JVM内存结构之-虚拟机栈】
  • 二极管的伏安特性与主要参数
  • C++笔记-封装红黑树实现set和map
  • 【工具类】常用的工具类——CollectionUtil
  • 服务器数据迁移终极指南:网站、数据库、邮件无缝迁移策略与工具实战 (2025)
  • iOS 直播弹幕礼物功能详解
  • HarmonyOS 鸿蒙应用开发基础:转换整个PDF文档为图片功能
  • 【软考架构】2025系统架构设计师开坑指南——后端开发(科目选择,考试大纲,真题分析)
  • vue2组件对象传参
  • Minecraft Fabric - java.lang.NoClassDefFoundError HttpUriRequest
  • windows 下用yolov5 训练模型 给到opencv 使用
  • CSS padding(填充)
  • CSS2相关知识点
  • C语言拼接4字节数据为uint32_t
  • 【CSS学习笔记1】css基础知识介绍
  • 2025年开源大模型技术全景图
  • Mistral AI 开源最新 Small 模型——Devstral-Small-2505
  • 从源码编译支持ffmpeg(H264编码)的opencv(创建mp4视频报错:H264 is not supported with codec id 28)
  • 【动手学深度学习】2.3. 线性代数
  • AWS云与第三方通信最佳实践:安全、高效的数据交互方案
  • NDVI谐波拟合(基于GEE实现)
  • Cat.4+WiFi6工业路由器介绍小体积大作用ER4200
  • 第29周———Inception v3算法实战与解析
  • epub→pdf | which 在线转换??好用!!
  • uniapp uts 插件开发指南
  • 多模态AI终极形态?GPT-5与Stable Diffusion 3的融合实验报告
  • C++中IOstream解析
  • 二十三、面向对象底层逻辑-BeanDefinitionParser接口设计哲学
  • 公有云AWS基础架构与核心服务:从概念到实践
  • Windows 使用 WSL 安装 Ubuntu