channel value garbage collection

608 views
Skip to first unread message

jonathan...@gmail.com

unread,
Apr 25, 2015, 12:30:22 AM4/25/15
to golan...@googlegroups.com
Quick question here, when value types are in a channel and the channel is garbage collected, are the values immediately collected to, or are they collected on their own?
Also if the values are read by some other goroutine and then that function exits, is there any kind of escape analysis that can put those on the stack or is it all still heap?

Thanks!

Dave Cheney

unread,
Apr 25, 2015, 12:54:37 AM4/25/15
to golan...@googlegroups.com
There is no way to tell if values garbage collected are collected immediately or after some time, and time is a tricky concept with multiple goroutines.

As you cannot take the address of a value inside the channel, there is no way for a goroutine to hold a reference to a value enqueued inside a channel.

Dave

Ian Lance Taylor

unread,
Apr 25, 2015, 12:59:59 PM4/25/15
to jonathan...@gmail.com, golang-nuts
On Fri, Apr 24, 2015 at 9:30 PM, <jonathan...@gmail.com> wrote:
>
> Quick question here, when value types are in a channel and the channel is
> garbage collected, are the values immediately collected to, or are they
> collected on their own?

I assume you are talking about a buffered channel.

With the current GC implementation, when the channel is not
referenced, the values in the channel buffer are also not referenced.
Therefore, they should all be collected in the same sweep phase. The
sweep phase is of course not instantaneous, so I don't know how to
answer whether the values are "immediately" collected.


> Also if the values are read by some other goroutine and then that function
> exits, is there any kind of escape analysis that can put those on the stack
> or is it all still heap?

I'm sorry, I don't understand the question.

There is currently no escape analysis that tracks values across
channels. I'm not sure how such an analysis could work.

Ian

jonathan...@gmail.com

unread,
Apr 25, 2015, 4:53:19 PM4/25/15
to golan...@googlegroups.com, jonathan...@gmail.com
Yes that's what I was wondering in the first question whether those values would be caught in the same sweep. Probably a dumb question because everything that can be is freed in each sweep?

My second question might not make sense sorry, i'll try to clarify. Imagine two goroutines, one created within the other as an anonymous function, both using a single channel created in the first goroutine, both served by the same OS thread. Does it now, or is it feasible in the future that the channel and its values could be allocated on the first goroutines stack?

I probably am missing something fundamental about the go runtime that would answer it for me (perhaps that there is no guarantee the same OS thread serves if GOMAXPROCS > 1?) What led me to the thought was whether to pass a channel back from a function or create it and pass it in instead. If there are no design decisions about which should control whether its buffered or not, I thought may be there is a performance difference.

Thanks guys

Ian Lance Taylor

unread,
Apr 25, 2015, 6:08:03 PM4/25/15
to jonathan...@gmail.com, golang-nuts
On Sat, Apr 25, 2015 at 1:53 PM, <jonathan...@gmail.com> wrote:
>
> My second question might not make sense sorry, i'll try to clarify. Imagine
> two goroutines, one created within the other as an anonymous function, both
> using a single channel created in the first goroutine, both served by the
> same OS thread. Does it now, or is it feasible in the future that the
> channel and its values could be allocated on the first goroutines stack?
>
> I probably am missing something fundamental about the go runtime that would
> answer it for me (perhaps that there is no guarantee the same OS thread
> serves if GOMAXPROCS > 1?) What led me to the thought was whether to pass a
> channel back from a function or create it and pass it in instead. If there
> are no design decisions about which should control whether its buffered or
> not, I thought may be there is a performance difference.

If you could prove that the lifetime of a goroutine exceeded the
lifetime of a buffered channel, then you could conclude that values
sent on the channel did not escape. Using a nested function doesn't
help one way or another. You would have to prove first that the
channel does not escape--that you can observe all uses of the channel.
The channel would have to be used in a for/range statement or
something equivalent--you would have to know for sure when all values
on the channel had been read. You would have to know for sure that
all values were read before the sending function finished, implying
the use another channel or a mutex or something to let the receiver
tell the sender that it was done. You would have to know for sure
that there were no panics anywhere in the sending function--no nil
pointer deferences, no calls to unknown functions that might panic.

I doubt many real programs could pass this analysis. I doubt anybody
would ever bother writing it. If it were written, I doubt it would be
worth adding to the compiler--it would increase compile time for all
programs for the benefit of very few programs.

Ian

Dave Cheney

unread,
Apr 25, 2015, 6:09:29 PM4/25/15
to golan...@googlegroups.com
First question: once all references to a value allocated on the heap are lost you cannot prove or disprove that that memory was ever reclaimed. Garbage collection is tricky like that.

Second question: the channel will be heap allocated.

jonathan...@gmail.com

unread,
Apr 25, 2015, 8:37:10 PM4/25/15
to golan...@googlegroups.com
Thanks guys for the very detailed answers, just what I was looking for, I appreciate it!
Reply all
Reply to author
Forward
0 new messages