Page 244 - 《软件学报》2026年第3期
P. 244
李清伟 等: Go 语言程序的内存性能与安全问题实证研究 1207
动态内存分配分析与优化提出挑战, 而 call 模式则针对跨函数的过程间动态内存分配分析与优化提出挑战. 另外
ret 模式也存在一定的比例, 揭示了过程间动态内存分配优化的潜力.
表 5 转换为接口的模式分布以及被转换类型分布
形式 类别 数量 比例 (%) 接口类型 (%) 非指针类型 (%) 指针类型 (%)
LHS = RHS assign 920 949 20.16 71.69 23.65 4.66
o.m(a1, a2) call 3 540 073 77.48 45.51 37.24 17.26
(interface{})(src) conversion 4 751 0.10 5.20 64.11 30.69
return a ret 100 806 2.21 6.56 56.04 37.08
ch <- a send 2 218 0.05 9.20 81.61 9.20
总计 4 568 797 100.00 49.92 34.96 15.11
进一步分析被转换为接口类型的数据类型的分布, 本文将这些类型分为 3 类: 接口类型、非指针类型和指针
类型. 接口类型和指针类型在转化为接口类型时不需要动态分配新对象. 非指针类型转换为接口类型需要动态分
配新的转换前类型对象. 3 种类型对象被转换为接口类型的分布如表 5 所示. 在 assign 和 call 模式中, 接口类型的
转换频率较高, 在 conversion、ret 和 send 模式中, 非指针类型占据主导, 这导致了显著的隐式堆内存分配需求. 因
此, 在进行内存优化时, 应优先关注非指针类型转换的分配问题, 以减少隐式分配带来的性能开销.
结论 2. 在接口类型转换的模式中, assign 模式和 call 模式两类模式占据绝大部分, 表明分析接口相关的内
存分配时应重点关注这两类模式. 此外, 由于非指针类型转换为接口类型需要在堆上新分配对象, 在涉及优化
conversion、ret、send 模式时需要特别注意这些隐式的堆内存分配. 由于 assign 和 call 模式基数较大, 其中非指针
类型转换为接口类型引发的隐式堆分配也是值得内存优化关注的点.
4 RQ2: 内存安全问题模式
围绕开源 Go 语言项目中的内存安全问题, 本节首先确定研究内存安全问题的关键词, 然后统计通过不同关
键词搜索得到的 Issues 数量分布, 以回答 RQ2 中的内存安全问题存在性和分布问题, 并分析出现较多内存安全问
题的仓库的领域分布, 以揭示 RQ2 中仓库领域与内存安全问题之间的关系. 最后本节总结与 3 个关键词相关的内
存安全问题的模式.
4.1 内存安全相关问题筛选
本文从 CVE [34] 、CWE [35] 和 Go 官方维护的漏洞数据库 [36] 搜索内存安全问题. 其中, 只有 CWE 提供了对内存
安全问题的分类总结, 包含了 C、C++、Java、PHP 等语言中的常见内存安全问题以及不同年份的 Top N 安全问
题视图 [37] . 由于 CWE 中未涵盖 Go 语言特定内存问题的视图, 本文基于 CWE 的两个视图——CWE Top 25 (2022) [38]
和 Software Written in C++ [39] , 筛除非内存安全问题和在 Go 语言中不太可能出现的问题, 结合 Go 语言在运行时
检查中常见的报错信息 [40] , 筛选出以下 3 个关键词, 分别为“memory leak”“invalid memory address OR nil pointer”
“dangling pointer”. 其中, “memory leak” 是指内存泄漏问题, 归属于 LEAK; “invalid memory address OR nil pointer”
通常在应用程序执行时由 Go 运行时检测到空指针解引用时报错, 归属于 NPD. “dangling pointer”则是指资源对象
(如内存对象或文件描述符对象) 被释放之后, 内存中还包含对这些已释放资源的引用, 归属于 DP. 基于这 3 个关
键词, 本文使用图 4 所展示的方法, 搜索了 996 个 Go 语言仓库过去 5 年内更新的 Issues/PRs 以及包含 memory 关
键词的 Issues/PRs, 后者可视为内存安全问题的总集. 基于这些 Issues/PRs, 对含内存安全问题的仓库的领域特点
进行分析, 借此进一步探索内存安全问题在不同领域的发生情况.
4.2 内存安全问题分布
本节将基于内存安全相关的 Issues/PRs 的数量, 分析内存安全问题在实际 Go 应用中的分布情况.
4.2.1 内存安全问题数量分布
根据图 4, 针对从 GitHub 中获取的 996 个最近 1 年内更新的仓库, 通过设置 3 类关键词进行搜索, 得到了不

