-
Notifications
You must be signed in to change notification settings - Fork 2
参数逃逸报错问题复现与解决
Jakegogo edited this page Oct 17, 2024
·
1 revision
package badcase
import (
"github.com/agiledragon/gomonkey"
"runtime"
"sync"
"testing"
)
//go:noinline
func a(i *Arg) int {
return 1
}
var arr = make([]*Arg, 0)
// TestEscape 测试参数逃逸
func TestEscape(t *testing.T) {
gomonkey.ApplyFunc(a, func(i *Arg) int {
wg := sync.WaitGroup{}
wg.Add(100)
for k := 0; k < 100; k++ {
go func() {
// 触发栈扩容
runtime.GC()
for j := 0; j < 100000; j++ {
cpy := &Arg{field1: i.field1}
arr = append(arr, cpy)
}
wg.Done()
}()
}
wg.Wait()
return len(i.field1)
})
// 调用被mock函数
arg := &Arg{field1: "ok"}
print(a(arg))
// 修复方式
//go func() {
// if arg == nil {
// print(arg)
// }
//}()
}
// Arg 测试用参数
type Arg struct {
field1 string
}
对引用对象进行深拷贝:
cpy := &Arg{field1: cloneString(i.field1)}
func cloneString(s string) string {
if len(s) == 0 {
return ""
}
b := make([]byte, len(s))
copy(b, s)
return *(*string)(unsafe.Pointer(&b))
}