Apakah punca kebocoran memori golang?
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.
Beberapa situasi di mana golang boleh menyebabkan kebocoran ingatan dengan mudah
1. Penggunaan pemasa yang tidak betul
1.1 Penggunaan masa.After()
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) } }
1.2 kali.Sumber NewTicker tidak dikeluarkan dalam masaApabila menggunakan masa.NewTicker, anda perlu secara manual panggil kaedah Stop() untuk melepaskan sumber, jika tidak, ia akan menyebabkan kebocoran memori kekal
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) } }
2 Apabila menggunakan pilih, jika terdapat kes yang tidak meliputi keadaan sepenuhnya dan tiada cawangan lalai untuk diproses, ia akhirnya akan menyebabkan kegagalan memori Kebocoran
2.1 Situasi yang membawa kepada penyekatan goroutineSituasi di atas akan menyekat penggunaan ch3 dan menyebabkan kebocoran memori
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) } }
Apabila keadaan gelung di atas mencecah lalai, melahu gelung akan berlaku, dan akhirnya CPU akan Meningkat
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 terbahagi terutamanya kepada menyekat tulis dan menyekat bacaSaluran kosong
Menyekat tulismenyekat 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) }
- Saluran penimbal disekat kerana penimbal penuh disekat
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) }
- Mengharapkan untuk membaca data daripada saluran, hasilnya tiada data Tulis goroutine dalam
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. Kebocoran memori disebabkan oleh goroutine
4.1 Memohon untuk terlalu banyak goroutineSebagai contoh, memohon terlalu banyak goroutine dalam gelung for dan tidak melepaskannya tepat pada masanya membawa kepada kebocoran ingatan
4.2 Penyekatan Goroutine
4.2.1 Masalah I/OSambungan I/O tidak mempunyai set tamat masa, menyebabkan goroutine terus menunggu dan kod akan meneruskan blok.
4.2.2 Kunci Mutex tidak dilepaskan
goroutine tidak boleh mendapatkan sumber kunci, menyebabkan goroutine disekat
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) }
Apabila program buntu, goroutine lain juga akan menyekat
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) }
Ketakpadanan dalam bilangan Tambah, Selesai dan tunggu dalam kumpulan tunggu akan menyebabkan menunggu terus menunggu
5. Kebocoran memori disebabkan oleh hirisanApabila dua keratan berkongsi alamat, satu daripadanya ialah pembolehubah global, yang satu lagi tidak boleh menjadi GC; belum dibersihkan.
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 }
Oleh itu, kepingan atau penunjuk biasanya digunakan untuk memindahkan tatasusunan besar dalam senario parameter formal untuk mengelakkan lonjakan jangka pendek dalam penggunaan memori [Cadangan berkaitan: Pergi video Tutorial
,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!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Masalah Threading Giliran di GO Crawler Colly meneroka masalah menggunakan Perpustakaan Colly Crawler dalam bahasa Go, pemaju sering menghadapi masalah dengan benang dan permintaan beratur. � ...

Perpustakaan yang digunakan untuk operasi nombor terapung dalam bahasa Go memperkenalkan cara memastikan ketepatannya ...

Apa yang perlu saya lakukan jika label struktur tersuai di Goland tidak dipaparkan? Apabila menggunakan Goland untuk Pembangunan Bahasa GO, banyak pemaju akan menghadapi tag struktur tersuai ...

Perbezaan antara percetakan rentetan dalam bahasa Go: perbezaan kesan menggunakan fungsi println dan rentetan () sedang ...

Perpustakaan mana yang dibangunkan oleh syarikat besar atau projek sumber terbuka yang terkenal? Semasa pengaturcaraan di GO, pemaju sering menghadapi beberapa keperluan biasa, ...

Masalah menggunakan redisstream untuk melaksanakan beratur mesej dalam bahasa Go menggunakan bahasa Go dan redis ...

Dua cara untuk menentukan struktur dalam bahasa Go: perbezaan antara VAR dan jenis kata kunci. Apabila menentukan struktur, pergi bahasa sering melihat dua cara menulis yang berbeza: pertama ...

Cecair mengendalikan isu keselamatan bersamaan dalam penulisan log pelbagai proses. Proses berganda menulis fail log yang sama pada masa yang sama. Bagaimana untuk memastikan kesesuaian selamat dan cekap? Ini ...
