背景
最近在学go语言,在腾讯云的服务器上进行代码学习,顺便刷leetcode。Go语言版本1.9,使用vscode远程连接进行代码书写。
崩溃经过
刷leetcode的过程中,由于不打算建太多的包,使用go test作为测试模块,某次debug过程中vscode的连接突然断线,且MobaXterm的连接也时断时续的,登陆腾讯云后台重启服务器解决问题。
在第二次出现问题之后,我开始排查原因,服务器的监控显示内存2G满载,系统盘IO读达到30000KB/s,刷leetcode达到这个读取速率绝对不正常。再次重启(重启速度也非常慢)
第三次再出现这类问题时,我开始怀疑是不是我写的代码导致系统崩溃。新建一个go目录将测试代码放入,使用go build编译运行。程序很快panic并被杀死,基本确定是代码引起的,开始排查。
崩溃原因
由于go语言没有自带的队列,于是我使用以下方法进行队列操作:
//初始化队列
queue:=make([]int,0)
//将元素e入队
queue=append(queue,e)
//将元素出队到e
e=queue[0]
queue=queue[1:]
//判空
len(queue)==0
由于我没有控制好入队的判断,导致队列越来越大,[]int数组不断进行扩张,直接导致内存吃满,开始使用硬盘进行虚拟内存交换,导致后续硬盘IO的高读取。
解决办法很简单,修改逻辑使其能不会无限入队,或者判断队列大小,过大的时候报panic即可
if len(queue) > 1000000 {
panic("too long")
}
未解决的问题
在测试的时候,同一份代码在使用go build编译、go run直接运行,在内存占用过高的时候都会停止。直接使用main函数进行的调试也会自动停止。
只有test模块中的run test和debug test会出现这个问题,还不清楚怎么限制test模块的内存使用