10 ms·
> The OCaml garbage collector is a modern hybrid generational/incremental collector which outperforms hand-allocation in most cases. Unlike the Java GC, which g
by pkhagah 9y ago
> The OCaml garbage collector is a modern hybrid generational/incremental collector which outperforms hand-allocation in most cases. Unlike the Java GC, which gives GCs a bad name, the OCaml GC doesn't allocate huge amounts of memory at start-up, nor does it appear to have arbitrary fixed limits that need to be overridden by hand.
From the linked article. Can anyone confirm or deny this? I have hard time believing this statement.
- Cieplak 9y ago@pron probably has the answer to this
- joshmarlow 9y agoJane Street are big players in the OCaml community (they build/maintain what's arguably the defacto standard library for the language - Jane Street Core) and apparently make a lot of money being good at what they do; so I'm inclined to believe them.
- haimez 9y agoDevils advocate: they're not doing anything better than anyone else in the market and they don't make a product. They're very invested in their ecosystem which is only as good as they make it because they have a very quiet, well funded (pun intended) echo chamber and a lot of spare cycles to maintain a STDLIB on top of their actual business.
- deleted 9y ago[deleted]
- gsb 9y agoAs far as it goes I think it is a pretty fair statement. However it is important to know of other decisions in the language which make it easier for the GC. Particularly, the use of tagged values and a GIL. Tagging makes it simpler to distinguish heap values from other values, and the GIL means that the GC does not need to operate concurrently.
- AlphaSite 9y agoIt may be the but from a couple of talks I've gotten they go to pretty extreme lengths to maintain that performance.
- searealist 9y agoIt's nonsense, the only way to make a GC fast is to use many times as much memory as manual management (about 6x to reach parity[1]). [1] https://people.cs.umass.edu/~emery/pubs/04-17.pdf https://people.cs.umass.edu/~emery/pubs/04-17.pdf
- rwmj 9y agoThis paper assumes that malloc/free is cost-free and that free is always called at the earliest possible place.
- mcguire 9y agoThe paper uses the Lea malloc, which is fast, but not free.
- rwmj 9y agoBy "cost-free" I mean that they use precise traces so that memory is always freed at the exact moment it is no longer used. So they underestimate (greatly IMHO) the memory used by malloc/free versus the garbage collector. It would be a superhuman programmer who always called free() on the line exactly following the last use of every piece of allocated memory. The second problem I have with the paper is that it underestimates the kinds of structures which GC makes possible -- eg sets of trees sharing nodes. And the corollary to that is that to implement those structures with malloc/free, programmers tend to reach for ref-counting, which adds to memory usage and is generally a terrible form of garbage collection for many other reasons. Nevertheless it's an interesting paper which does add to the debate (I studied it about 10 years ago). It is worth reading, even though I have concerns about the methodology and hence the results.
- searealist 9y ago> By "cost-free" I mean that they use precise traces so that memory is always freed at the exact moment it is no longer used. So they underestimate (greatly IMHO) the memory used by malloc/free versus the garbage collector. It would be a superhuman programmer who always called free() on the line exactly following the last use of every piece of allocated memory. Let's say you are correct, that the manual memory management presented in the paper is too unrealistic. What do you think real world manual memory management would bring the multiple to? 5x? 4x? > The second problem I have with the paper is that it underestimates the kinds of structures which GC makes possible -- eg sets of trees sharing nodes. And the corollary to that is that to implement those structures with malloc/free, programmers tend to reach for ref-counting, which adds to memory usage and is generally a terrible form of garbage collection for many other reasons. These data structures are extremely niche, and when used when sharing is not truly needed just lead to time/space inefficiencies.
- jblow 9y agoIt is simply not true unless you have a pathological idea of "hand-allocation" (which to be fair, some programmers do program like). Let me put it this way ... all "garbage collection is fast" claims are saying the following thing: "It is faster for the programmer to destroy information about his program's memory use (by not putting that information into the program), and to have the runtime system dynamically rediscover that information via a constantly-running global search and then use what it gleans to somehow be fast, than it is for the programmer to just exploit the information that he already knows." It sure sounds like nonsense to me.
- vvanders 9y agoYup, an arena allocator that you drop at the end of an operation will always be faster than a GC.
- gsb 9y agoAbsolutely, but I think the "in most cases" of the original quote was meant to imply simple malloc/free style memory management rather than the use of tailored arena/region allocators.
- _yosefk 9y agoWell, yeah, but if you need some of the allocated data at the end of the operation, you'll end up copying it, which will have a runtime cost, might introduce bugs (because of pointer invalidation and the ease of forgetting to update some pointers) and then none of the two will get counted as "cost of manual memory management." C++ with its value semantics encourages unnecessary copying tremendously and it's never counted as "cost of memory allocation" or "producing garbage", on the contrary, Stroustrup says things like "C++ is my favorite GC language because it generates so little garbage to begin with." This is not to say that it's fair to call OCaml "efficient" in the memory department based on a GC benchmark; TFA is full of examples where OCaml allocates things on the heap that TFA recommends to allocate elsewhere and shows you how to maul your code to get there. My only point is that how well a programming system uses memory is a very hard question because (A) there are many different use cases and (B) you can't isolate "memory performance" into a few easily measurable things like time spent allocating, time spent in GC and peak memory use - there are other things like what your program has to do outside of the allocator to cope with its semantics and how the performance of code using the memory objects is affected by the layout encouraged by the allocator and these things cannot be measured in isolation from the rest of the program.
- qznc 9y agoJava gave GCs a bad name? It made them mainstream!
- _ph_ 9y agoIn a sense, both :). Java made GC mainstream and since Hotspot has an excellent GC, solving the problem for many use cases. However, the Java language design is extremely performance-hostile with respect to memory allocations. Notable points are: - no value types mean, that there are tons of separate heap allocations which have to be referenced by pointers, this puts a ton of unnecessary load on the GC. It also means, that you fully depend on escape analysis when passing objects to functions for avoiding heap allocation. And the existing primitive types (int, float) often require boxing. - the design of the standard libraries was, especially at the beginning full of wasteful allocations. Most string handling code was a constant series of allocations (having 16 byte chars didn't help this either). - far to many Java libraries build extremely complex object hierarchies and protocols. Just reading from a text file means instantiating several objects. This adds to the GC pressure.
- dom0 9y agoA good example how to not write performance sensitive code, in general, and specifically in Java, would be Minecraft. Though commercially successful Minecraft is (or at least was) an excellent study of how to not do stuff, be it memory management, networking or rendering (when I played Minecraft it still used immediate mode GL if I recall correctly)
- mcguire 9y agoLet's break it down. Hopefully someone can fill in the parts I don't know. > The OCaml garbage collector is a modern hybrid generational/incremental collector which outperforms hand-allocation in most cases. Ocaml is mostly functional and likes to allocate many short lived objects. With enough memory, a moving collector is very good at handling that load. > Unlike the Java GC, which gives GCs a bad name, the OCaml GC doesn't allocate huge amounts of memory at start-up, nor does it appear to have arbitrary fixed limits that need to be overridden by hand. Java's GC (-s; there's a bunch) use a heap with a fixed maximum size and an initial allocation. It has also received much more research attention over the decades. It also has a lot of knobs to fiddle with. I've run production Java web app servers with multi-gig heaps where almost all requests were handled in the young generation. The knobs and visibility were very nice. Ocaml doesn't use a fixed size heap, so it can conceivably take over all of memory. It also doesn't have all of the knobs. But it works pretty well.