Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will the garbage collector collect Go routines that will never continue?

Consider the following code as a simplified example:

func printer(c <-chan int) {
    for {
        fmt.Print(<-c)
    }
}

func provide() {
    c := make(chan int)

    go printer(c)

    for i := 1; i <= 100; i++ {
        c <- i
    }
}

The function provide creates a go routine printer that prints the data provide generates.

My question is, what happens after provide returns and printer starts blocking on the empty channel. Will the go routine leak, as there is no further reference to c or will the garbage collector catch this case and dispose both the go routine and c?

If it is indeed the case that this kind of code causes a memory leak, what strategies can I do to prevent such a memory leak from happening?

like image 948
fuz Avatar asked May 16 '13 15:05

fuz


People also ask

Are Go routines garbage collected?

- Goroutines are not garbage collected.

How does garbage collector work in Golang?

Garbage collection is a mechanism Go developers use to find memory space that is allocated recently but is no longer needed, hence the need to deallocate them to create a clean slate so that further allocation can be done on the same space or so that memory can be reused.

How do you trigger garbage collection in Go?

Go allows you to manually initiate a garbage collection by putting a runtime. GC() statement in your Go code. However, have in mind that runtime. GC() will block the caller and it might block the entire program, especially if you are running a very busy Go program with many objects.

Is Golang garbage collected?

Go is a garbage collected language. This makes writing Go simpler, because you can spend less time worrying about managing the lifetime of allocated objects. Memory management is definitely easier in Go than it is in, say, C++. But it's also not an area we as Go developers can totally ignore, either.


1 Answers

Close the channel. Reading from a closed channel always succeeds, returning a respective zero value. The optional second boolean returned value indicates validity of the first value.

Receive operator:

A receive expression used in an assignment or initialization of the form

x, ok = <-ch
x, ok := <-ch
var x, ok = <-ch

yields an additional result of type bool reporting whether the communication succeeded. The value of ok is true if the value received was delivered by a successful send operation to the channel, or false if it is a zero value generated because the channel is closed and empty.

func printer(c <-chan int) {
        for {
                v, ok := <-c
                if !ok { // chan closed
                        return
                }

                // v is valid
                fmt.Println(v)
        }
}

func provide() {
        c := make(chan int)

        go printer(c)

        for i := 1; i <= 100; i++ {
                c <- i
        }
        close(c)
}
like image 68
zzzz Avatar answered Oct 21 '22 22:10

zzzz