概述
当前程序中有一段创建任务的代码,由于之前任务逻辑不复杂,任务存储的结构体字段较少。后续业务越来越复杂,结构体嵌套结构体得到了一个非常大的结构体Task。然后启动新协程的时候,copy了一份task的副本,导致参数超过了新goroutine的可用堆栈空间。 goroutine默认分配2k的内存。
伪代码
func CreateTask() {
//初始化任务信息,大量的逻辑代码
// ......
var task model.Task
err = setTaskInfo(¶ms, &task)
unsafe.Sizeof(task) // 这时task的大小已超过了2k了
// 直接panic了
go RecordTaskStartLogInfo(task)
// 下面两种方式没有该问题,后续若修改原task内容无影响,建议传指针
/*go func(){
RecordTaskStartLogInfo(task)
}()
go RecordTaskStartLogInfo(&task)*/
return
}
总结
结构体嵌套结构体,使用时一定要注意,结构体副本所占用的空间会越来越大,结构体嵌套结构体,能不用最好不要用这种方式。如果一定要使用,可以使用指针来替代副本做参数传递。