首次提交:初始化项目代码
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Person4 struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// closureEscape 返回闭包,捕获的变量逃逸
|
||||
func closureEscape() func() *Person4 {
|
||||
p := &Person4{Name: "Closure Person", Age: 30} // p 逃逸至堆
|
||||
return func() *Person4 {
|
||||
return p // 闭包引用p,延长其生命周期
|
||||
}
|
||||
}
|
||||
|
||||
// goroutineClosure 协程中使用闭包,捕获变量逃逸
|
||||
func goroutineClosure() {
|
||||
x := 100 // x 逃逸至堆
|
||||
go func() {
|
||||
fmt.Printf("协程闭包捕获:%d\n", x)
|
||||
}()
|
||||
}
|
||||
|
||||
func main() {
|
||||
closureFunc := closureEscape()
|
||||
p := closureFunc()
|
||||
fmt.Printf("闭包捕获变量:%+v\n", *p)
|
||||
|
||||
goroutineClosure()
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Animal 接口定义
|
||||
type Animal interface {
|
||||
Speak() string
|
||||
}
|
||||
|
||||
// Dog 实现Animal接口
|
||||
type Dog struct{}
|
||||
|
||||
func (d Dog) Speak() string {
|
||||
return "汪汪汪"
|
||||
}
|
||||
|
||||
// Cat 实现Animal接口
|
||||
type Cat struct{}
|
||||
|
||||
func (c Cat) Speak() string {
|
||||
return "喵喵喵"
|
||||
}
|
||||
|
||||
// interfaceEscape 变量赋值给接口,触发逃逸
|
||||
func interfaceEscape(animalType string) Animal {
|
||||
var a Animal
|
||||
if animalType == "dog" {
|
||||
d := Dog{} // d 逃逸至堆
|
||||
a = d
|
||||
} else {
|
||||
c := Cat{} // c 逃逸至堆
|
||||
a = c
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// interfacePointer 指针赋值给接口,触发逃逸
|
||||
func interfacePointer() interface{} {
|
||||
p := &Dog{} // p 逃逸至堆
|
||||
return p
|
||||
}
|
||||
|
||||
func main() {
|
||||
animal := interfaceEscape("dog")
|
||||
fmt.Printf("接口动态派发:%s\n", animal.Speak())
|
||||
|
||||
iface := interfacePointer()
|
||||
if dog, ok := iface.(*Dog); ok {
|
||||
fmt.Printf("接口指针逃逸:%s\n", dog.Speak())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// largeArrayEscape 大数组指针返回,触发逃逸
|
||||
func largeArrayEscape() *[10000]int {
|
||||
arr := new([10000]int) // 8MB(int占8字节),超过栈阈值,逃逸至堆
|
||||
for i := 0; i < 10000; i++ {
|
||||
arr[i] = i
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// smallArrayNoEscape 小数组,不逃逸
|
||||
func smallArrayNoEscape() [10]int {
|
||||
var arr [10]int
|
||||
for i := 0; i < 10; i++ {
|
||||
arr[i] = i
|
||||
}
|
||||
return arr // 值拷贝,不逃逸
|
||||
}
|
||||
|
||||
func main() {
|
||||
largeArr := largeArrayEscape()
|
||||
fmt.Printf("大数组逃逸:长度=%d\n", len(largeArr))
|
||||
|
||||
smallArr := smallArrayNoEscape()
|
||||
fmt.Printf("小数组不逃逸:%v\n", smallArr)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Person8 struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// noEscape 返回值类型,不逃逸
|
||||
func noEscape() Person8 {
|
||||
p := Person8{Name: "No Escape", Age: 25}
|
||||
return p // 值拷贝,生命周期局限于函数内
|
||||
}
|
||||
|
||||
// localVar 局部变量,未被外部引用,不逃逸
|
||||
func localVar() {
|
||||
x := 100
|
||||
y := "hello"
|
||||
p := Person8{Name: "Local", Age: 30}
|
||||
fmt.Printf("局部变量不逃逸:x=%d, y=%s, p=%+v\n", x, y, p)
|
||||
}
|
||||
|
||||
func main() {
|
||||
p := noEscape()
|
||||
fmt.Printf("返回值不逃逸:%+v\n", p)
|
||||
|
||||
localVar()
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// 优化1:避免不必要的指针传递(小结构体)
|
||||
// 优化前:指针传递,可能触发逃逸
|
||||
func processPersonOld(p *Person) string {
|
||||
return fmt.Sprintf("%s is %d years old", p.Name, p.Age)
|
||||
}
|
||||
|
||||
// 优化后:值传递,不逃逸
|
||||
func processPersonNew(p Person) string {
|
||||
return fmt.Sprintf("%s is %d years old", p.Name, p.Age)
|
||||
}
|
||||
|
||||
// 优化2:提前确定切片容量,避免动态扩容逃逸
|
||||
// 优化前:动态扩容,底层数组逃逸
|
||||
func sliceEscape() []int {
|
||||
s := make([]int, 0)
|
||||
for i := 0; i < 100; i++ {
|
||||
s = append(s, i)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// 优化后:指定容量,不逃逸
|
||||
func sliceNoEscape() []int {
|
||||
s := make([]int, 0, 100) // 编译期确定容量
|
||||
for i := 0; i < 100; i++ {
|
||||
s = append(s, i)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// 优化3:使用对象池复用对象,减少堆分配
|
||||
var personPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &Person{} // 初始化对象,仅分配一次(或按需分配)
|
||||
},
|
||||
}
|
||||
|
||||
// 优化前:频繁创建对象,多次堆分配
|
||||
func createPersonOld(name string, age int) *Person {
|
||||
return &Person{Name: name, Age: age} // 每次调用都逃逸,触发堆分配
|
||||
}
|
||||
|
||||
// 优化后:复用对象池中的对象,减少堆分配
|
||||
func createPersonNew(name string, age int) *Person {
|
||||
p := personPool.Get().(*Person)
|
||||
p.Name = name
|
||||
p.Age = age
|
||||
return p
|
||||
}
|
||||
|
||||
// 释放对象到池
|
||||
func releasePerson(p *Person) {
|
||||
// 重置对象状态(避免残留数据)
|
||||
p.Name = ""
|
||||
p.Age = 0
|
||||
personPool.Put(p)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 优化1测试
|
||||
p := Person{Name: "Alice", Age: 25}
|
||||
fmt.Println("优化1-值传递:", processPersonNew(p))
|
||||
|
||||
// 优化2测试
|
||||
s1 := sliceEscape()
|
||||
s2 := sliceNoEscape()
|
||||
fmt.Printf("优化2-切片:逃逸len=%d, 不逃逸len=%d\n", len(s1), len(s2))
|
||||
|
||||
// 优化3测试
|
||||
p1 := createPersonNew("Bob", 30)
|
||||
fmt.Println("优化3-对象池:", *p1)
|
||||
releasePerson(p1)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Person7 struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
Person7 *Person7 // 关联Person指针
|
||||
}
|
||||
|
||||
// GetPerson 返回关联的Person指针,触发逃逸
|
||||
func (m *Manager) GetPerson() *Person7 {
|
||||
return m.Person7 // Person指针逃逸
|
||||
}
|
||||
|
||||
// createManager 返回Manager指针,触发逃逸
|
||||
func createManager() *Manager {
|
||||
m := &Manager{
|
||||
Person7: &Person7{Name: "Manager Person", Age: 40}, // Person逃逸
|
||||
}
|
||||
return m // Manager指针逃逸
|
||||
}
|
||||
|
||||
func main() {
|
||||
manager := createManager()
|
||||
person := manager.GetPerson()
|
||||
fmt.Printf("方法接收者逃逸:%+v\n", *person)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// 全局变量,存储Person指针
|
||||
var globalPerson *Person2
|
||||
|
||||
// 全局切片,存储Person指针
|
||||
var globalPersonSlice []*Person2
|
||||
|
||||
type Person2 struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// storePerson 接收指针参数并返回,触发逃逸
|
||||
func storePerson(p *Person2) *Person2 {
|
||||
return p // 指针被返回,触发逃逸
|
||||
}
|
||||
|
||||
// addToGlobal 将指针存入全局变量,触发逃逸
|
||||
func addToGlobal() {
|
||||
p := &Person2{Name: "Bob", Age: 30}
|
||||
globalPerson = p // 存入全局变量,p逃逸
|
||||
}
|
||||
|
||||
// addToGlobalSlice 将指针存入全局切片,触发逃逸
|
||||
func addToGlobalSlice() {
|
||||
for i := 0; i < 3; i++ {
|
||||
p := &Person2{Name: fmt.Sprintf("Person%d", i), Age: 20 + i}
|
||||
globalPersonSlice = append(globalPersonSlice, p) // p逃逸至切片
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
p := &Person2{Name: "Charlie", Age: 28}
|
||||
storedP := storePerson(p)
|
||||
fmt.Printf("引用传递:%+v\n", *storedP)
|
||||
|
||||
addToGlobal()
|
||||
fmt.Printf("全局变量存储:%+v\n", *globalPerson)
|
||||
|
||||
addToGlobalSlice()
|
||||
fmt.Printf("全局切片存储:%d个Person\n", len(globalPersonSlice))
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Person 测试结构体
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// newPerson 返回局部变量指针,触发逃逸
|
||||
func newPerson(name string, age int) *Person {
|
||||
p := &Person{Name: name, Age: age} // p 逃逸至堆
|
||||
return p
|
||||
}
|
||||
|
||||
func main() {
|
||||
p := newPerson("Alice", 25)
|
||||
fmt.Printf("局部变量指针返回:%+v\n", *p)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Person3 struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
// sliceEscape 切片元素为指针,且切片被返回,元素逃逸
|
||||
func sliceEscape() []*Person3 {
|
||||
var people []*Person3
|
||||
for i := 0; i < 3; i++ {
|
||||
person := &Person3{Name: fmt.Sprintf("Person3%d", i), Age: 20 + i}
|
||||
people = append(people, person) // person 逃逸
|
||||
}
|
||||
return people
|
||||
}
|
||||
|
||||
// dynamicSlice 切片动态扩容,底层数组逃逸
|
||||
func dynamicSlice() []int {
|
||||
s := make([]int, 0) // 编译期无法确定最终容量
|
||||
for i := 0; i < 100; i++ {
|
||||
s = append(s, i) // 扩容时底层数组逃逸
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// mapEscape 映射值为指针,值逃逸
|
||||
func mapEscape() map[string]*Person3 {
|
||||
m := make(map[string]*Person3)
|
||||
m["alice"] = &Person3{Name: "Alice", Age: 25} // 指针值逃逸
|
||||
return m
|
||||
}
|
||||
|
||||
func main() {
|
||||
people := sliceEscape()
|
||||
fmt.Printf("切片元素逃逸:%d个Person\n", len(people))
|
||||
|
||||
s := dynamicSlice()
|
||||
fmt.Printf("切片扩容逃逸:len=%d, cap=%d\n", len(s), cap(s))
|
||||
|
||||
m := mapEscape()
|
||||
fmt.Printf("映射值逃逸:%+v\n", *m["alice"])
|
||||
}
|
||||
Reference in New Issue
Block a user