Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will time.Tick cause memory leak when I never need to stop it?

Tags:

go

Consider the following code:

go func() {
    for now := range time.Tick(time.Minute) {
        fmt.Println(now, statusUpdate())
    }
}()

I need the for loop runs forever and never need to stop it. Will this cause memory leak or not?

I knew if I ever need to break the for loop, it will cause memory leak. But what if I don't need to break the for loop?

The doc says

While Tick is useful for clients that have no need to shut down the Ticker, be aware that without a way to shut it down the underlying Ticker cannot be recovered by the garbage collector; it "leaks".

I just want to get it right.

like image 853
sgon00 Avatar asked Sep 19 '25 05:09

sgon00


1 Answers

First, let's see a definition of what a "memory leak" is, from Wikipedia:

In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in a way that memory which is no longer needed is not released.

It's important to note that in the doc you quoted, it does not specifically mention a "memory leak", just a "leak" (meaning "resource leak"). The resources in question are not only the memory used by the ticker, but the goroutine that runs it. Because of this, I'll interpret this definition as applying to "resource leaks" more broadly.

As mentioned by the doc you quoted, time.Tick does not make it possible to release the ticker's resources.

So by this definition, if the ticker is no longer needed at any subsequent point in the program, then a resource leak has occurred. If the ticker is always needed for the remainder of the program after created, then it's not a leak.

Further in the Wikipedia definition, however, is this note:

A memory leak may also happen when an object is stored in memory but cannot be accessed by the running code.

Again, time.Tick does not make it possible to release the ticker's resources.

So by this continued definition, you might say that the use of time.Tick is always a resource leak.

In practical terms, as long as you range over the time.Tick without breaking, you have reasonable assurance that the ticker is going to continue to be used for the remainder of the program, and there will be no "leak". If you have any doubts of if a ticker will be used forever, then use time.NewTicker and Stop() it appropriately:

go func() {
    ticker := time.NewTicker(time.Minute)
    defer ticker.Stop()

    for now := range ticker.C {
        fmt.Println(now, statusUpdate())
        // some exception
        if (something) {
            break
        }
    }
}()
like image 50
Hymns For Disco Avatar answered Sep 23 '25 12:09

Hymns For Disco