具事故具体过程与分析见 http://readfrog.ltd/index.php/archives/58/
写不动了,先放个大概在这里
GoGC回收缓慢
1)GC 只能回收“已经死掉”的对象
如果 Xray 里还有活跃对象,比如:
连接状态
缓冲区
goroutine
session / mux / tls cache
某些 map / queue / stats
那 GC 再勤快也没法收。
所以第一层问题是:
这些内存到底是不是垃圾?
如果不是垃圾,GC 完全无能为力。
2)即使对象是垃圾,GC 回收后 RSS 也未必立刻掉
这是 Go 很容易让人误判的地方。
对象回收后,内存可能只是从:
HeapAlloc
变成
HeapIdle
但仍然保留在 Go 进程手里。
所以你从系统角度看,还是觉得:
这个进程很肥
宿主机可用内存还是少
thrashing 还在
于是你会觉得“GC 没干活”,其实它可能干了,只是没及时把 RSS 还给 OS。
3)在 thrashing 里,GC 自己也会推进困难
你这次最麻烦的就在这里。
GC 不是神仙,它也要:
跑代码
扫堆
访问内存页
被调度到 CPU
而 thrashing 状态下正好:
page cache 被疯狂回收
代码页反复缺页
磁盘读打爆
进程调度被拖慢
所以 GC 本身也会“救火救到自己都快烧着”。
这不是 Go 独有,但 Go 这种长寿服务特别容易撞上。



































































































































