Sebab kebocoran adalah: 1. Penggunaan masa.Selepas(setiap kali.Selepas(tempoh x) akan menjana NewTimer() Sebelum tempoh x tamat, pemasa yang baru dibuat tidak akan GC , GC hanya akan berlaku selepas tamat tempoh. Sumber NewTicker tidak dikeluarkan dalam masa;
Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.
Masa lalai.After() mempunyai masalah kebocoran memori, kerana setiap kali.After(tempoh x) akan menjana NewTimer( ), pemasa yang baru dibuat tidak akan GCed sebelum tempoh x tamat, dan hanya akan GCed selepas tamat tempoh.
Semakin masa berlalu, terutamanya jika tempoh Kaedah alternatif secara aktif mengeluarkan sumber Sila semak perbezaan antara kedua-duanya sendiri atau baca artikel saya sebelum ini https://blog.csdn.net/weixin_38299404/article/. details/119352884
for true { select { case <-time.After(time.Minute * 3): // do something default: time.Sleep(time.Duration(1) * time.Second) } }
timer := time.NewTicker(time.Duration(2) * time.Second) defer timer.Stop() for true { select { case <-timer.C: // do something default: time.Sleep(time.Duration(1) * time.Second) } }
timer := time.NewTicker(time.Duration(2) * time.Second) // defer timer.Stop() for true { select { case <-timer.C: // do something default: time.Sleep(time.Duration(1) * time.Second) } }
func main() { ch1 := make(chan int) ch2 := make(chan int) ch3 := make(chan int) go Getdata("https://www.baidu.com",ch1) go Getdata("https://www.baidu.com",ch2) go Getdata("https://www.baidu.com",ch3) select{ case v:=<- ch1: fmt.Println(v) case v:=<- ch2: fmt.Println(v) } }
func main() { fmt.Println("main start") msgList := make(chan int, 100) go func() { for { select { case <-msgList: default: } } }() c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill) s := <-c fmt.Println("main exit.get signal:", s) }
menyekat saluran yang tidak dibuffer biasanya merupakan operasi menulis yang menyekat kerana tiada bacaan
func channelTest() { //声明未初始化的channel读写都会阻塞 var c chan int //向channel中写数据 go func() { c <- 1 fmt.Println("g1 send succeed") time.Sleep(1 * time.Second) }() //从channel中读数据 go func() { <-c fmt.Println("g2 receive succeed") time.Sleep(1 * time.Second) }() time.Sleep(10 * time.Second) }
func channelTest() { var c = make(chan int) //10个协程向channel中写数据 for i := 0; i < 10; i++ { go func() { <- c fmt.Println("g1 receive succeed") time.Sleep(1 * time.Second) }() } //1个协程丛channel读数据 go func() { c <- 1 fmt.Println("g2 send succeed") time.Sleep(1 * time.Second) }() //会有写的9个协程阻塞得不到释放 time.Sleep(10 * time.Second) }
func channelTest() { var c = make(chan int, 8) //10个协程向channel中写数据 for i := 0; i < 10; i++ { go func() { <- c fmt.Println("g1 receive succeed") time.Sleep(1 * time.Second) }() } //1个协程丛channel读数据 go func() { c <- 1 fmt.Println("g2 send succeed") time.Sleep(1 * time.Second) }() //会有写的几个协程阻塞写不进去 time.Sleep(10 * time.Second) }
func channelTest() { var c = make(chan int) //1个协程向channel中写数据 go func() { <- c fmt.Println("g1 receive succeed") time.Sleep(1 * time.Second) }() //10个协程丛channel读数据 for i := 0; i < 10; i++ { go func() { c <- 1 fmt.Println("g2 send succeed") time.Sleep(1 * time.Second) }() } //会有读的9个协程阻塞得不到释放 time.Sleep(10 * time.Second) }
4.2.3 Deadlock
//协程拿到锁未释放,其他协程获取锁会阻塞 func mutexTest() { mutex := sync.Mutex{} for i := 0; i < 10; i++ { go func() { mutex.Lock() fmt.Printf("%d goroutine get mutex", i) //模拟实际开发中的操作耗时 time.Sleep(100 * time.Millisecond) }() } time.Sleep(10 * time.Second) }
4.2.4 Penggunaan kumpulan tunggu yang tidak betul
func mutexTest() { m1, m2 := sync.Mutex{}, sync.RWMutex{} //g1得到锁1去获取锁2 go func() { m1.Lock() fmt.Println("g1 get m1") time.Sleep(1 * time.Second) m2.Lock() fmt.Println("g1 get m2") }() //g2得到锁2去获取锁1 go func() { m2.Lock() fmt.Println("g2 get m2") time.Sleep(1 * time.Second) m1.Lock() fmt.Println("g2 get m1") }() //其余协程获取锁都会失败 go func() { m1.Lock() fmt.Println("g3 get m1") }() time.Sleep(10 * time.Second) }
6 Pemindahan nilai tatasusunan
Memandangkan tatasusunan ialah jenis data asas Golang, setiap tatasusunan menduduki jumlah memori yang berbeza space. , kitaran hayat tidak mengganggu satu sama lain, dan sukar untuk menyebabkan kebocoran memori Walau bagaimanapun, apabila tatasusunan dihantar sebagai parameter formal, salinan nilai masa diikuti Jika fungsi dipanggil oleh berbilang goroutine tatasusunan terlalu besar, ia akan menyebabkan lonjakan penggunaan memori.var a []int func test(b []int) { a = b[:3] return }
Pengajaran Pengaturcaraan
]//统计nums中target出现的次数 func countTarget(nums [1000000]int, target int) int { num := 0 for i := 0; i < len(nums) && nums[i] == target; i++ { num++ } return num }
Atas ialah kandungan terperinci Apakah punca kebocoran memori golang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!