News for hackers. Stuff that matters.
Re:GC Tuning Confessions of a Performance Engineer by pron on Friday May 29, 2015 @06:27PM (#9627879)
I think we should look at the problem the other way around: it is manual memory management that is overkill because there are exactly four kinds of object memory scope:

* stack scope * transaction scope (for some definition of transaction -- it can be, say, a frame in a game, or a request in a web server) * arbitrary (database or any shared data structure) * permanent

For the stack scope, we have the stack. For the arbitrary scope, a GC is invaluable. For the permanent scope, it doesn't matter too much whether you have a GC or not (yes, vitalyd is going to mention traversals, but if the traversals are interesting, they point to objects in the arbitrary cost anyway). This leaves us the transaction cost. Now, I think it is far easier to manage a stack scope in a GCed environment than an arbitrary scope in a manual environment, and, in fact, some GCs, such as HotSpot's G1 should (yes, vitalyd, it doesn't always work) figure out the tranaction boundary automatically, but even if they don't, it's fairly easy to get that functionality with object pooling. However, to get the absolute best we shouldn't add a GC to a manually managed environment, but add arena collections to a GCed environment, which is exactly what RTSJ (realtime Java) does with scoped memory (making sure there are no references from potentially longer scopes into the arena).

To sum up, for the absolute best performance, a GCed environment + arenas has all you need. There is absolutely no need for a per-object malloc/free, and reference counting is neither here nor there (contention, cycles).

Re:GC Tuning Confessions of a Performance Engineer by pcwalton on Friday May 29, 2015 @06:33PM (#9627912)
> yes, vitalyd is going to mention traversals, but if the traversals are interesting, they point to objects in the arbitrary cost anyway

I'm going to mention this too. I don't understand what you mean by "they point to objects in the arbitrary cost anyway". The fact of the matter is that you have to trace all objects at some point.

> Now, I think it is far easier to manage a stack scope in a GCed environment than an arbitrary scope in a manual environment, and, in fact, some GCs, such as HotSpot's G1 should (yes, vitalyd, it doesn't always work) figure out the tranaction boundary automatically, but even if they don't, it's fairly easy to get that functionality with object pooling.

Object pooling is just a (limited, error-prone, poorly-performing) form of manual memory management.

> reference counting is neither here nor there (contention, cycles).

Contention isn't a problem if you don't touch the reference counts much. Cycles aren't a problem if you don't have cycles.

Re:GC Tuning Confessions of a Performance Engineer by pron on Saturday May 30, 2015 @01:47PM (#9630991)
> I'm going to mention this too.

What I mean is that either those refs are permanent -- in which case they won't be traced -- or arbitrary -- in which case it's really more of an "arbitrary" problem than a "permanent" one.

> Object pooling is just a (limited, error-prone, poorly-performing) form of manual memory management.

... And reference counting is just a (limited, error-prone, poorly-performing) form of garbage collection.

> Contention isn't a problem if you don't touch the reference counts much. Cycles aren't a problem if you don't have cycles.

But now you've added restrictions that are much more onerous than those of object-pools.

In any case, my main question is this: if absolute top performance is what you need, why not have a GC + arenas (like RTSJ) without ref counting/manual management? In my opinion, there's only one downside to that approach is RAM footprint. If that's your answer, then I agree (I think that that's pretty much the main reson not to use a GC).

Re:GC Tuning Confessions of a Performance Engineer by vitalyd on Friday May 29, 2015 @07:23PM (#9628140)
>I'm going to mention this too. I don't understand what you mean by "they point to objects in the arbitrary cost anyway". The fact of the matter is that you have to trace all objects at some point.

I think he means that if you have object references, then those references are interesting for the application itself, and not just for the GC tracer. However, I don't buy this statement simply because, even if you elect to store things as references rather than interior allocs, your app will only pointer chase the things it cares about, whereas the GC tracer may chase pointers that your app wouldn't otherwise.

@Ron:

The "arbitrary" scope better not be really arbitrary since even GCs are typically tuned for the generational hypothesis: your objects better be either short lived or long lived, anything in between is likely to degrade GC performance. In fact, if you like at some of the big data java solutions, once they reach a certain heap size, GC starts killing them, and they end up building their own semi-hybrid solution of moving stuff off-heap, and then managing that memory themselves (using the exact same block/slab/arena allocation techniques being downplayed here!).

For things like databases where object lifetime is in the hands of the user, arena/slab allocators work just fine. The additional advantage here is that you rarely need to destroy just a single object somewhere, typically it's an entire blob of related stuff. Arena destruction is more efficient here than GC because it's it inherently has more context than GC (the engineer wrote it, afterall). Is it more challenging/harder to implement than simply punting to the GC? Probably yes. But if you run afoul of GC's ergonomics and/or need to start tuning the finer points of GC behavior (i.e. see above comment about most of the big data java projects hitting this wall), the time spent there may end up exceeding arena impl costs.

Re:GC Tuning Confessions of a Performance Engineer by pron on Saturday May 30, 2015 @12:46AM (#9629015)
> I think he means that if you have object references, then those references are interesting for the application itself, and not just for the GC tracer.

What I mean is that either those refs are permanent -- in which case they won't be traced -- or arbitrary -- in which case it's really more of an "arbitrary" problem than a "permanent" one.

> The "arbitrary" scope better not be really arbitrary since even GCs are typically tuned for the generational hypothesis

By arbitrary I mean long-lived (old-gen) but not permanent. In short: database data.

> For things like databases where object lifetime is in the hands of the user, arena/slab allocators work just fine.

What you are saying is that you never truly have arbitrary-lifetime objects, and I strongly disagree with that.

> the time spent there may end up exceeding arena impl costs.

Even if you're right about arenas (which I don't agree with), you believe that a runtime designed to target the vast majority of server software should force developers to figure out lifetimes and that that may be beneficial to them? I mean, I even mentioned arena just to get that much closer to 100% performance. Even without them Java gets to at least 90%. Are you suggesting that the vast majority of projects in the world are interested in doing more work that is likely error prone just to get that 10% at best?