Page 247 - 《软件学报》2026年第3期
P. 247
1210 软件学报 2026 年第 37 卷第 3 期
表 10 内存泄漏 LEAK 问题的人工分类
LEAK 问题类 LEAK 问题子类 Issues 数量
L1-1: 配对资源未被一起释放 2
L1: 资源未被显式释放 8
L1-2: 缺少对释放函数的调用 6
L2-1: 逻辑错误导致程序中的显式释放函数并没有被调用 2
L2: 不正确的显式释放 L2-2: 分配多次, 释放一次 2 5
L2-3: 使用切片表达式前没有删除底层数组隐式引用 1
L3-1: 协程独占的数据结构过多 1
L3: 并发 2
L3-2: 并发阻塞导致协程资源泄漏 1
L4-1: 旧版本存在内存泄漏 4
L4: 依赖项内存泄漏 5
L4-2: 使用依赖项的默认参数时内存使用量较大 1
L5: 拷贝大内存 L5-1: append 拷贝了内存占用量大的切片 1 1
L6-1: 不合理的回收机制导致待回收对象仍然被长期引用 1
L6: 分配和回收速率不匹配 2
L6-2: 分配时复用较少 1
总计 23
● L1: 资源未被显式释放. 在程序中缺少对资源显式释放函数的调用, 从而造成资源的泄漏. 在该问题类中包
含 3 个小类, 模式代码如代码 5 所示.
代码 5. L1: 资源未被显式释放问题模式.
1. // L1-1: pingcap/tidb/issues/27353
2. func (x *Resource) Close() {
3. + if x.pairResource != nil {
4. + x.pairResource.Close() // add close here
5. + }
6. }
7. // L1-2: defer grpc/grpc-go/issues/6642
8. ticker := time.NewTicker( ...)
9. + defer ticker.Stop() // add Stop here
10. // L1-2: error pingcap/tidb/issues/34666
11. if err != nil {
12. + resource.Close() // add close here
13. return err
14. }
15. // L1-2: otherref btcsuite/btcd/pull/2105
16. + if c.batch { // fix here
17. + c.batchList.Remove(element) // fix here
18. + } else {
19. c.requestList.Remove(element)
20. + }
L1-1: 配对资源未被一起释放. 某些资源在定义时会引用其他配对资源. 当申请特定资源时, 通常会同时申请
配对资源; 而当特定资源释放时, 配对资源也应一并释放. 然而由于 Go 语言中自动垃圾回收并不会调用配对资源
的释放函数, 导致配对资源未被释放, 进而产生内存泄漏. 代码 5 中第 1–6 行展示了 tidb 的 Issue#27353 [43] 的简化

