Page 239 - 《软件学报》2026年第3期
P. 239
1202 软件学报 2026 年第 37 卷第 3 期
4.66 GiB 6k
5k
3.73 GiB 4k
内存使用量 2.79 GiB Clients数量 3k
1.86 GiB
954.00 MiB 2k
1k
0
0 B 15:40 15:50 16:00 16:10 16:20 16:30 15:40 15:50 16:00 16:10 16:20 16:30
时刻 时刻
Resident memory Resident memory Connected XDS clients
(a) Memory usage (b) Number of clients
图 1 grpc/grpc-go/issues/4758 内存泄漏问题, 在用户数量下降之后, 内存使用量仍然保持不变
代码 3. grpc-go Issue#4758: slice 操作前未置空导致内存泄漏.
1. var item *itemType
2. − item, q.queue = q.queue[0], q.queue[1:] // q.queue[0] will not be used forever
3. + item = q.queue[0]
4. + q.queue[0] = nil
5. + q.queue = q.queue[1:]
6. ... // destroy item
1.4 面向 Go 语言程序的内存安全问题检测工具
为了缓解内存安全问题, 除了 Go 语言采用的运行时崩溃等机制, 一些代码检查工具也被开发和使用.
Staticcheck [12] 是一个较为先进的 Go 语言代码检查工具, 能够检测标准库的误用、并发问题、冗余代码和内存性
能等问题. 针对内存安全问题, Staticcheck 包括了对冗余 nil 检查 [26–29] 、可能发生空指针解引用的检测 [30] 等分析
规则. golangci-lint [14] 集成了多个代码检查工具, 支持代码风格检查, 未使用函数和变量的检查等. go vet 工具 [13] 作
为 Go 语言内置的检查工具, 可以检测 defer 使用时的常见错误、不必要的比较函数指针和 nil 模式等.
尽管这些检测工具在发现和修复常见的编程错误方面发挥了重要作用, 但它们仍然存在一定的局限性. 因此,
对 Go 语言内存安全问题进行实证分析显得尤为重要. 通过对 Go 代码中的内存安全问题进行深入研究, 可以帮助
开发者设计和构建更有效的代码检查工具, 从而更早发现潜在的内存安全隐患.
2 方法设计
为了深入探讨 Go 语言的内存性能和安全问题及其关联模式, 本文设计了如后文图 2 所示的分析框架 PatStat.
针对 RQ1, 基于 CodeQL [31] 设计了统计分析工具 QLStat, 能对不同基本访存操作进行全面统计分析. 针对 RQ2, 设
计了 IssueAnalyzer 工具, 能通过关键词检索 GitHub 的 Issues/PRs, 结合统计与人工分析, 总结 Go 语言中内存安全
问题的分布特征及常见代码模式. 针对 RQ3, 为 RQ2 中识别的典型内存问题模式编写查询语句, 利用 QLStat 工具
对选择的 Go 代码仓库 (repository, Repo) 进行扫描查询, 以发现潜在的内存安全问题, 并探索可能的自动检测
方法.
本文通过 GitHub 的 REST API 获取了最近 1 年内有更新的 Go 语言代码仓库. 选择最近 1 年内更新的仓库,
旨在确保其处于积极维护状态, 能够反映 Go 语言生态的活跃部分及当前发展趋势和实际应用情况. 最终, 共收集
到 996 个仓库, 并且基于这些仓库开展后续的模式统计分析.
2.1 RQ1: 访存操作的模式统计
为了回答 RQ1, 设计了如图 3 所示的 QLStat, 基于抽象语法树 (AST) 识别 Go 语言项目中不同基本访存操作
并统计分布情况, 为编译器优化提供指导. QLStat 基于 CodeQL 对代码仓库进行模式匹配, 合并各仓库的分析结
果, 从而实现不同基本访存操作的统计分析. CodeQL 是一款代码扫描工具, 能够提取程序的多种信息, 如抽象语

