背景

Go 语言中有对应的Go 内存回收机制,在Go采用 并发三色标记清除  算法, 但是由于实际的过程中 发现会有一些内存泄漏的常见,内存泄漏 分为: 临时性 和 永久性内存泄漏。

初步排查过程中: 发现Linux使用top 发现内存随着时间会持续的增加没有稳定在一个合理值中。

在使用 pprof ,BBC 等 Go的内存泄漏工具进行排查

临时性内存泄漏

指的释放内存 不及时,对应的内存在更晚时候释放,这类问题主要是 string,slice 和底层的Buffer 错误共享,或者defer 函数资源没有及时的释放。

数组不正常使用导致内存泄漏

数组作为形参 遵守的是 值拷贝,如果函数调用次数很多并且数组过大,导致 内存使用激增

大数组在形参的场景下,通常使用的是切片方式。或者使用指针进行传递,避免在短时间内内存激增

goroutine 没有及时释放

一个 goroutine 创建 2KB

通道理解

通道 channel 属于Go语言中首次提出的 运用 goroutine 的进行数据交换的 容器;

  • 缓冲通道属于一个元素队列, 有先入先出原则, 属于线程安全
  • 如果通道满了, 发送goroutine 会阻塞直到 read goroutine 进行接收操作
  • 如果通道是空的, 执行接收goroutine 阻塞直到 write goroutine 在通道上发送数据;
  • 通道既不满也不空,所以通道的缓冲区将发送和接收 goroutine 进行解耦操作

如果程序直到 缓冲区的容量, 可以调用 内置的  cap函数 cap(ch) -- 缓冲区容量
len(ch) -- 缓冲区内 元素个数

goroutine 泄漏: 使用一个无缓冲通道,两个慢的 goroutine 卡住,发送的响应的结果没有其他的goroutine 接收 这个情况属于 goroutine 泄漏;

如果读速度比较快,缓冲区存是没有意义的