Page 235 - 《软件学报》2026年第3期
P. 235
1198 软件学报 2026 年第 37 卷第 3 期
memory access in Go programs, at 25.44% and 17.63%, respectively. This indicates the importance of field sensitivity and points-to
analysis in Go program analysis and optimization. Moreover, implicit memory allocation resulting from Go’s unique interface type
conversions is another key area for optimization. Through manual analysis of 130 Issues involving memory leaks, invalid memory
addresses or null pointer dereferences, and dangling pointers, the study identifies 10 Issue patterns, noting that dangling pointer problems
are rare in Go. These Issues typically require around 30 days for resolution but often demand only a few dozen lines of code changes.
The findings offer insights for optimizing Go programs and mitigating memory safety concerns. Furthermore, a linter is developed to
detect the Issue pattern, which involves the assignment of a slice expression that may lead to memory leaks. This tool identifies 6 Issues
in real-world projects, one of which receives positive feedback.
Key words: Go; memory performance; static code analysis; memory safety; empirical study
Go 语言是一门新兴现代编程语言, 由 Google 在 2009 年开源. Go 语言凭借其语法特性简洁、内存自动管理、
编译速度快、原生支持高并发等特点, 在许多如容器、云原生、数据库、无服务器架构、微服务等新兴软件场
景 [1] 中被广泛使用.
作为一门兼顾开发效率与执行效率的新兴语言, Go 语言在内存管理方面兼具灵活性与自动化. 一方面, 它支
持类似 C/C++的指针和寻址操作, 提供了较高的灵活性; 另一方面, 它通过引入垃圾回收进行自动内存管理, 降低
了人工内存管理的成本. Go 的内存管理采用了编译与运行时结合的方式. 在编译时, 利用逃逸分析确定对象的分
配位置, 将部分对象分配在栈上以提高程序的内存性能; 在运行时, 垃圾回收器负责动态内存的自动回收, 同时通
过检测机制在一定程度上避免诸如内存泄漏、空指针解引用等安全问题. 然而, 这套独特的内存访问与管理机制,
也使得 Go 程序面临独特的内存安全和性能问题.
Go 语言的特殊内存管理机制虽然带来了便捷性, 但也存在一定的性能问题和内存安全隐患, 这些问题引发了
社区和学术界的讨论和改进尝试.
[2]
一方面, Go 的垃圾回收机制在处理生命期相似的对象时效率有限. 例如, Go 社区提案 Issue#51317 建议引
入 arena 机制, 通过整体分配和释放生命期相近对象的内存区域来提升性能, 该功能已在 Go 1.20 中实验性支持.
此外, 一些编程模式也可能引发性能问题. Wang 等人 [3] 发现, 将对象转换为接口并作为实参传递的操作可能导致
不必要的堆分配, 为此他们用正则表达式识别相应的模式并绕过逃逸分析来减少堆内存分配量. Ding 等人 [4] 研究
表明, Go 的逃逸分析算法存在保守建模问题, 导致一些不必要的堆内存分配, 他们通过为逃逸分析引入域敏感性
和指向分析, 能够在增加较小编译开销的情况下提升分析精度和程序性能. Peng 等人 [5] 则通过显式识别和回收短
生命期的堆对象, 减少了垃圾回收的开销并提高了内存利用效率.
另一方面, 尽管 Go 语言引入了垃圾回收和运行时检测机制, 但却无法完全避免内存安全问题. 例如, 在远程
[7]
[6]
过程调用框架 grpc-go 中的 Issue#4758 中, 在客户端连接数量减少、服务负载降低后, 内存未能按预期减少, 导
致内存泄漏. 此外, 并发问题也是开发中常见的挑战. Liu 等人 [8] 使用 GCatch 工具发现了 149 个并发阻塞问题, 而
Veileborg 等人 [9] 进一步发现了 104 个并发阻塞问题. 这些表明, 尽管 Go 的内存管理机制已经相对完善, 但仍有改
进空间, 开发者需要关注并应对相关问题.
针对上述内存性能与安全问题, 静态代码模式识别与优化往往是有效的解决方案. 例如, Selakovic 等人 [10] 总
结了 JavaScript 性能问题的常见代码模式, 指导开发者和分析人员进行优化. Liu 等人 [8] 利用 GCatch 工具识别信
道阻塞问题的代码模式, 并通过 GFix 自动修复. Chabbi 等人 [11] 则针对数据竞争问题总结了相关的代码模式. Go
语言社区也存在较多通过规则和模式匹配的工具 (如 Staticcheck [12] 、go vet [13] 、golangci-lint [14] 、gosec [15] 、revive [16]
等), 用于检测非内存安全问题和并发问题. 然而, 针对 Go 的内存性能优化和非并发类内存安全问题的模式识别和
检测的工作仍较少.
基于以上观察, 希望通过静态代码分析, 对 Go 语言的内存性能优化问题和非并发类内存安全问题进行实证
研究. 研究将探索 Go 语言的内存访问特征及其问题模式, 帮助开发者识别并避免潜在的问题, 并为社区提供有关
内存管理优化的见解, 推动 Go 工具链的改进.
本文主要围绕以下 3 个研究问题 (RQ) 展开实证探究.

