Does method with pointer receiver keeps track of the receiver instance

147 views
Skip to first unread message

Tony Yang

unread,
Jul 24, 2020, 7:07:33 PM7/24/20
to golang-nuts
Hi Go community,

I am wondering if a method with the pointer receiver keeps the receiver instance from garbage collected.

To put the idea into a code example

```
type counter struct {
c int
}

func (c *counter) next() int {
c.c = c.c + 1
return c.c
}

func getNextFunc() func () int {
// Question: will c be garbage collected after the function retruns?
c := &counter{}
return c.next
}
```


Ian Lance Taylor

unread,
Jul 24, 2020, 7:21:35 PM7/24/20
to Tony Yang, golang-nuts
The mere existence of a pointer receiver does not prevent a value from
being garbage collected. In your example, if the counter value is
allocated on the heap in getNextFunc, that heap allocation can be
collected after getNextFunc returns (in practice in this example c
would be allocated on the stack, not the heap, anyhow).

Ian

burak serdar

unread,
Jul 24, 2020, 7:26:15 PM7/24/20
to Ian Lance Taylor, Tony Yang, golang-nuts
What is returned from the function is a method, though. Isn't that
essentially a closure keeping a reference to c, and thus, c has to be
allocated on the heap, and cannot be garbage collected until the
returned function leaves the scope?

>
> Ian
>
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcWtFocDKraHsR-fqadrKgYxc%2B5K9e9u1rM7K%3DRj3oLXMw%40mail.gmail.com.

Tony Yang

unread,
Jul 24, 2020, 7:39:25 PM7/24/20
to golang-nuts
I have tried the following example: https://play.golang.org/p/OfeWQH5S-Ju

```
func main() {
nextFunc := getNextFunc()
fmt.Println(nextFunc()) // prints 1
fmt.Println(nextFunc()) // prints 2
runtime.GC()
fmt.Println(nextFunc()) // prints 3
fmt.Println(nextFunc()) // prints 4
}
```

It appears that the receiver c is not GCed, or maybe it is GCed but the corresponding memory hasn't been clean up yet.

If it wasn't GCed, I am wondering how does Go bookkeep c.

Tony

Ian Lance Taylor

unread,
Jul 24, 2020, 11:26:38 PM7/24/20
to burak serdar, Tony Yang, golang-nuts
On Fri, Jul 24, 2020 at 4:25 PM burak serdar <bse...@computer.org> wrote:
>
> On Fri, Jul 24, 2020 at 5:21 PM Ian Lance Taylor <ia...@golang.org> wrote:
> >
> > On Fri, Jul 24, 2020 at 4:07 PM Tony Yang <tony...@umich.edu> wrote:
> > >
> > > Hi Go community,
> > >
> > > I am wondering if a method with the pointer receiver keeps the receiver instance from garbage collected.
> > >
> > > To put the idea into a code example
> > >
> > > ```
> > > type counter struct {
> > > c int
> > > }
> > >
> > > func (c *counter) next() int {
> > > c.c = c.c + 1
> > > return c.c
> > > }
> > >
> > > func getNextFunc() func () int {
> > > // Question: will c be garbage collected after the function retruns?
> > > c := &counter{}
> > > return c.next
> > > }
> >
> > The mere existence of a pointer receiver does not prevent a value from
> > being garbage collected. In your example, if the counter value is
> > allocated on the heap in getNextFunc, that heap allocation can be
> > collected after getNextFunc returns (in practice in this example c
> > would be allocated on the stack, not the heap, anyhow).
>
>
> What is returned from the function is a method, though. Isn't that
> essentially a closure keeping a reference to c, and thus, c has to be
> allocated on the heap, and cannot be garbage collected until the
> returned function leaves the scope?

My apologies, I completely missed that you returned a method rather
than calling the method.

Yes, doing this will prevent c from garbage collected. Otherwise it
would be impossible to call the returned function safely.

Ian

Tony Yang

unread,
Jul 26, 2020, 10:14:27 PM7/26/20
to Ian Lance Taylor, burak serdar, golang-nuts
No problem, thanks!
Reply all
Reply to author
Forward
0 new messages