Hacker News new | past | comments | ask | show | jobs | submit login
Simpler and faster GC for Go (docs.google.com)
190 points by xkarga00 on July 17, 2014 | hide | past | favorite | 33 comments



Slightly off topic, but is there a good (i.e., fast and easy to use) modern retargetable GC for language prototyping/implementation? I've been looking for something like this for a while, but it seems everyone rolls their own.


Basic mark & sweep is simple to understand and implement. See e.g. https://code.google.com/p/tinypy/source/browse/trunk/tinypy/... - 136 lines of C code in tinypy. You'll find more examples if you look at other small implementations.

But you also want fast, at which point you have to accept that fast gc == complicated and tightly coupled to the implementation details (object layout, type/debug info).

There is no pluggable GC. Conservative GCs (like Boehm GC) come the closest, but they have significant drawbacks (they blindly scan all of memory and can't tell a difference between a pointer and a random number that looks like a pointer, which means scanning&marking phase take longer and they keep objects that could have been freed, which is especially a problem on 32bits, where it's more likely that a random number points inside GC-managed heap).



You could try using http://www.hboehm.info/gc/

An alternative is to do reference counting (in your prototyping phase), which is much easier to implement.


For prototyping could you use malloc without free? I have been rolling my own GC and wish that I would have left this until later.


lua-jit reference is conspicuously missing : http://wiki.luajit.org/New-Garbage-Collector


> GC scanning and marking phase is 10-20% faster for programs with large number of small objects.

Which is most programs. Hurray, changes in good direction.


In Go you avoid allocations for small values and use the stack.


To be fair, we do that to avoid GC slowdown issues. If the GC improves to the point where that's no longer an issue, we don't have to do that anymore :)


A 30% improvement is nice but nowhere near enough to change programming best practices in go.

A significant algorithmic change in the GC, like a generational compacting GC or something along those lines, would have to be made to alter go programming strategies.


Do you do that explicitly or is at a compiler optimization?


Both. If you deal with a value type (struct or primitive) and never take the address of it, it can't exist anywhere besides the current stack, value types are copied if you return it out of a function or call another function with it.

For reference types, they do have escape analysis, not sure how one would compare it to another language.


God of Speed Dmitry Vyukov.


Dmitry is in my personal programmer hall of fame.


Ditto, the guy is a real software engineer.


Yeah, it was an honor to meet and talk with him in person at the last golang meetup. His incredible work is inspiring and motivating.


I don't see this on golang-dev at all. I'm interested to see the discussion around it.


The code review has discussion: https://codereview.appspot.com/106260045


I agree.

But it has always bothered me how he declares pointers! :-)

(stack[pointer] s, node[pointer] n)

Instead of

(stack [pointer]s, node [pointer]n)

Am I picky? :-)

[pointer] is the * just trying to avoid the italics conversion of HN.


I remember I was going back and forth between the two over the years, and I had to keep looking up which was my "latest" preferred style.

I eventually came to the following,

(stack [pointer] s, node [pointer] n)

Since it's symmetrical, it's easy to remember.

Luckily, I've been using Go and gofmt (goimports, specifically) the last 2 years so this is no longer an issue.





Pro-tip for google docs: you can use /preview instead of /pub to get a much more readable version of the document (pagination, &c.).


No mention of a generational collector. The word concurrent is in there though.


In 1.3 the GC is concurrent mark and sweep


I thought generational and mark/sweep were orthogonal. That is, can't generational still be mark and sweep? You just don't mark and sweep the entire reference set?


Generational collectors can pick any strategy for each of their generations. What to pick depends on language, and what characteristics you want to get easily.


Recounting for tenured generations would be awesome!


Why mod someone down for asking about a generational GC?


My comment was a little flip, I know, I should have asked a more friendly question. I'm wondering why it hasn't been discussed (as far as I can tell). Java has had it for ages, Ruby will have it in 2.1 and Python appears to have it as well [1]. Isn't Generational GC feasible in Go for some reason?

[1] https://docs.python.org/2/library/gc.html

Edit: Here is a discussion of gc in go. Go has only just gotten a precise collector, which is a requirement of a generational gc, to allow moving pointers.

https://groups.google.com/forum/#!topic/golang-nuts/fiOs3mGH...


I've heard talk of plans for a generational, moving GC in future. It's just not something that can be implemented overnight, especially in a language with internal pointers (which Java, Ruby and Python lack).


FYI: Ruby 2.1 has been released for some time now.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: