5 ms·
I'm aware of Ian's arguments. He's (a) too dismissive of the huge throughput benefits of generational GC; (b) ignoring the fact that both HotSpot and C# allocat
by pcwalton 8y ago
I'm aware of Ian's arguments. He's (a) too dismissive of the huge throughput benefits of generational GC; (b) ignoring the fact that both HotSpot and C# allocate objects on the stack too, with effectively superior escape analysis to that of Go because of speculative devirtualization; (c) neglecting the fact that Go's situation is almost the same as that of .NET, where the generational hypothesis certainly holds; (d) treating "request-oriented" GC as something other than generational GC, when it's really just a somewhat limited form of generational GC.
It's just a pointless thing for the Go team to dig in their heels over. They should implement generational GC, like most other languages with optimizing compilers do.
- stcredzero 8y agoHe's (a) too dismissive of the huge throughput benefits of generational GC; The ObjectStudio VM engineers used to lament over the advantage the VisualWorks GC had: VisualWorks only had to garbage collect one thread. ObjectStudio had gone multi-threaded, and to stop the world, the VM had to signal all of the threads, and wait for all of them to come to an inactive state. The more parallelism in the form of more machine threads, the higher this penalty is likely to be. treating "request-oriented" GC as something other than generational GC, when it's really just a somewhat limited form of generational GC. Isn't it more accurate to say that it's a simpler way of getting to use low cost bump allocation and very low cost deallocation? Even generational GC needs some knowledge and skill from programmers to achieve the highest level of efficiency. (Or even some modicum of knowledge to keep it from failing.) The golang request-oriented hypothesis just moves the cost-benefit tradeoff knobs. To get beyond middling performance, you still have to profile and optimize either way. Profiling allocation is usually straightforward.
- pcwalton 8y ago> The ObjectStudio VM engineers used to lament over the advantage the VisualWorks GC had: VisualWorks only had to garbage collect one thread. I'm not sure what this is trying to imply. Modern generational GCs use TLABs to solve this exact problem.
- stcredzero 8y ago> TLAB Thread Local Allocation Buffer. Cool. Doesn't the stack in golang serve somewhat the same purpose? I've sometimes wondered about golang going the direction of Erlang, with multiple independent GCs. (Not per goroutine. It would have to be per "Actor" which I find myself implementing again and again in golang.) Modern generational GCs use TLABs to solve this exact problem. So that solves the problem on allocation, while the generational hypothesis reduces the frequency of stop the world. Generalizing in this fashion, I don't see why generational GC is inevitably necessary. With golang, the stack provides cheap allocation to local threads, even with concurrency, and throughput isn't as big a deal, with a bit more work needed by the programmer for optimization. (But perhaps my view would change with access to more data or with more experience.)
- littlestymaar 8y ago> I don't see why generational GC is inevitably necessary But remind that almost everybody having to implement a GC (but the Go team) thinks otherwise. Do you believe you know more than langage runtime engineers ? Because that's Go folks seams to believe, and that's anoyingly arrogant…
- foldr 8y agoThe fact that Go has acceptable GC performance surely shows that it's not inevitably necessary.
- weberc2 8y agoI've seen you rebut Ian's remarks a number of times. I'm not sufficiently knowledgeable about GCs, but I would really like to hear some of his responses to your criticisms. I think I (and probably lots of others) would learn a lot from the debate.
- geodel 8y agoThere is most likely none. Go team at Google would have enough real usage feedback from running Go systems in their massive data centers. They most likely find it reasonable with all things considered. This debate about Generational GC is theoretical in nature, claiming Java GC design is universally applicable irrespective of language and its use cases. There may indirect approval to Go approach by Java when developing value types: http://openjdk.java.net/jeps/169 http://openjdk.java.net/jeps/169 key Quote: "In modern JVMs, object allocation is inexpensive, with a cost comparable to out-of-line procedure calling. But even this cost is often a painful overhead when compared to individual operations on primitive values. Thus, Java programmers face a binary choice between existing primitive types (which avoid allocation) and other types (which allow data abstraction and other benefits of classes). When they need to define small composite values such as complex numbers, pixels, or pairs of return values, neither approach serves. This dilemma often has no good solution, and the workarounds distort Java programs and APIs. " If we go by claims that Java and its GC supporters always made: 1) RAM is Cheap 2) GC is incredibly fast so as not to worry about allocation. There should be no need to waste tremendous multi year engineering effort to add value types to Java.
- openasocket 8y agoThat's a straw man. Just because GC is fast doesn't mean it can't be made faster. > Go team at Google would have enough real usage feedback from running Go systems in their massive data centers. They most likely find it reasonable with all things considered. That's not just an appeal to authority, that's a big assumption. As far as I know, no Go maintainer has claimed that they have gathered large amounts of performance data and concluded that a generational GC wouldn't improve performance. Also, calling generational GC "Java GC design" is disingenuous. Generational GC long precedes the creation of Java, and is used almost universally. Common Lisp (various implementations), .Net, the Lua VM (and the LuaJIT VM), BEAM, SELF, and Haskell (GHC at least) all use generational garbage collection. In fact, the current Go implementation is the only GC implementation I'm aware of that isn't generational.