search
HomeBackend DevelopmentGolangWhat are the causes of golang memory leaks?

What are the causes of golang memory leaks?

Jan 10, 2023 pm 05:45 PM
golanggo languagememory leak

The reasons for the leak are: 1. The use of time.After(). Each time.After(duration x) will generate NewTimer(). Before duration x expires, the newly created timer will not be GC , GC will only occur after expiration; 2. time.NewTicker resources are not released in time; 3. select blocking; 4. channel blocking; 5. applying for too many goroutines, goroutine blocking; 6. caused by slice, etc.

What are the causes of golang memory leaks?

The operating environment of this tutorial: Windows 7 system, GO version 1.18, Dell G3 computer.

Several situations in which golang can easily lead to memory leaks

1. Improper use of timers

1.1 The use of time.After()

The default time.After() will have a memory leak problem, because each time.After(duration x) will generate NewTimer( ), the newly created timer will not be GCed before duration x expires, and will only be GCed after expiration.

As time goes by, especially if the duration The method actively releases resources. Please check the difference between the two by yourself or read my previous articles 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)
	}
}

1.2 time.NewTicker resources are not released in timeWhen using time.NewTicker, you need to manually call the Stop() method to release resources, otherwise it will cause a permanent memory leak

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. Select blockingWhen using select, if there is a case that does not fully cover the situation and there is no default branch for processing, it will eventually lead to memory leaks

2.1 Situations that cause goroutine to block
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)
	}
}
The above situation will block the consumption of ch3 and cause memory leaks

2.2 Loop idling causes CPU surge
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)
    }
}
Once the above for loop condition hits default, loop idling will occur, which will eventually lead to CPU surge

3. Channel blockingChannel blocking is mainly divided into two situations: write blocking and read blocking

Empty channel

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)
}

Write blocking

The blocking of unbuffered channel is usually that the write operation blocks because there is no read.
  • 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)
    }

The buffered channel is blocked because the buffer is full. , write operation blocked
  • 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)
    }
  • read blocked

Waiting to read data from the channel, but no goroutine went in to write data
  • 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)
    }

4. Memory leak caused by goroutine

4.1 Apply for too many goroutines

For example, applying for too many goroutines in a for loop and not releasing them in time leads to memory leaks

##4.2 Goroutine blocking4.2. 1 I/O problem

The I/O connection does not set a timeout, causing the goroutine to keep waiting and the code to keep blocking.

4.2.2 The mutex lock is not releasedgoroutine cannot obtain the lock resource, causing goroutine to block
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 DeadlockWhen the program deadlocks, other goroutines will also block
//协程拿到锁未释放,其他协程获取锁会阻塞
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 Improper use of waitgroupThe mismatch in the number of Add, Done and wait of waitgroup will cause wait to keep waiting

5. Memory caused by slice LeakWhen two slices share an address, one of which is a global variable, the other cannot be GC;

It has been used after appending the slice without cleaning it.

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. Array value transferSince arrays are the basic data type of Golang, each array occupies a different amount of memory space. The cycles do not interfere with each other, so it is difficult to cause memory leaks. However, when the array is transmitted as a formal parameter, the time value copy is followed. If the function is called by multiple goroutines and the array is too large, it will cause a surge in memory usage.
var a []int
 
func test(b []int) {
        a = b[:3]
        return
}

Therefore, when large arrays are placed in formal parameter scenarios, slices or pointers are usually used to pass them to avoid a short-term surge in memory usage.

[Related recommendations:

Go video tutorial

Programming teaching

The above is the detailed content of What are the causes of golang memory leaks?. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
The Performance Race: Golang vs. CThe Performance Race: Golang vs. CApr 16, 2025 am 12:07 AM

Golang and C each have their own advantages in performance competitions: 1) Golang is suitable for high concurrency and rapid development, and 2) C provides higher performance and fine-grained control. The selection should be based on project requirements and team technology stack.

Golang vs. C  : Code Examples and Performance AnalysisGolang vs. C : Code Examples and Performance AnalysisApr 15, 2025 am 12:03 AM

Golang is suitable for rapid development and concurrent programming, while C is more suitable for projects that require extreme performance and underlying control. 1) Golang's concurrency model simplifies concurrency programming through goroutine and channel. 2) C's template programming provides generic code and performance optimization. 3) Golang's garbage collection is convenient but may affect performance. C's memory management is complex but the control is fine.

Golang's Impact: Speed, Efficiency, and SimplicityGolang's Impact: Speed, Efficiency, and SimplicityApr 14, 2025 am 12:11 AM

Goimpactsdevelopmentpositivelythroughspeed,efficiency,andsimplicity.1)Speed:Gocompilesquicklyandrunsefficiently,idealforlargeprojects.2)Efficiency:Itscomprehensivestandardlibraryreducesexternaldependencies,enhancingdevelopmentefficiency.3)Simplicity:

C   and Golang: When Performance is CrucialC and Golang: When Performance is CrucialApr 13, 2025 am 12:11 AM

C is more suitable for scenarios where direct control of hardware resources and high performance optimization is required, while Golang is more suitable for scenarios where rapid development and high concurrency processing are required. 1.C's advantage lies in its close to hardware characteristics and high optimization capabilities, which are suitable for high-performance needs such as game development. 2.Golang's advantage lies in its concise syntax and natural concurrency support, which is suitable for high concurrency service development.

Golang in Action: Real-World Examples and ApplicationsGolang in Action: Real-World Examples and ApplicationsApr 12, 2025 am 12:11 AM

Golang excels in practical applications and is known for its simplicity, efficiency and concurrency. 1) Concurrent programming is implemented through Goroutines and Channels, 2) Flexible code is written using interfaces and polymorphisms, 3) Simplify network programming with net/http packages, 4) Build efficient concurrent crawlers, 5) Debugging and optimizing through tools and best practices.

Golang: The Go Programming Language ExplainedGolang: The Go Programming Language ExplainedApr 10, 2025 am 11:18 AM

The core features of Go include garbage collection, static linking and concurrency support. 1. The concurrency model of Go language realizes efficient concurrent programming through goroutine and channel. 2. Interfaces and polymorphisms are implemented through interface methods, so that different types can be processed in a unified manner. 3. The basic usage demonstrates the efficiency of function definition and call. 4. In advanced usage, slices provide powerful functions of dynamic resizing. 5. Common errors such as race conditions can be detected and resolved through getest-race. 6. Performance optimization Reuse objects through sync.Pool to reduce garbage collection pressure.

Golang's Purpose: Building Efficient and Scalable SystemsGolang's Purpose: Building Efficient and Scalable SystemsApr 09, 2025 pm 05:17 PM

Go language performs well in building efficient and scalable systems. Its advantages include: 1. High performance: compiled into machine code, fast running speed; 2. Concurrent programming: simplify multitasking through goroutines and channels; 3. Simplicity: concise syntax, reducing learning and maintenance costs; 4. Cross-platform: supports cross-platform compilation, easy deployment.

Why do the results of ORDER BY statements in SQL sorting sometimes seem random?Why do the results of ORDER BY statements in SQL sorting sometimes seem random?Apr 02, 2025 pm 05:24 PM

Confused about the sorting of SQL query results. In the process of learning SQL, you often encounter some confusing problems. Recently, the author is reading "MICK-SQL Basics"...

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.