4 ms·
I have always wondered why people, especially game developers, have such a hatred of GC. As I understand it, GC has a higher throughput than malloc/free. This c
by James_K 2y ago
I have always wondered why people, especially game developers, have such a hatred of GC. As I understand it, GC has a higher throughput than malloc/free. This comes at the cost of pauses, but that is essentially just quantising overhead into discrete chunks. In the context of a video game, I always thought you could design a GC that runs once at the end of every frame and thereby causes no stuttering at all and gets to completely ignore all objects allocated and discarded during the frame. A performance win, no?
I've only ever come to two conclusions. The first is that the cost of garbage collection is much higher than I estimate, but I have seen no empirical proof of that, and many game engines seem to use garbage collected scripting languages without issue. The second conclusion is that Java's lack of value-types means every program needs to allocate small objects like mad and that degrades performance, which has made most people view GC as slower than it would be if you took a C++ program and swapped the calls to new out with calls to some garbage collected allocator. Do you have any insight on this? What profiling have you done to conclude GC performs worse?
- neonsunset 2y agoA lot of gamedevs have been burned by Unity's Boehm GC (I assume the situation has improved in recent years? Please let me know.). Keep in mind that outside of Minecraft, Java is not popular for writing games where the high-ish level language of choice is usually C# instead, both with Unity and many other open or closed source engines, that either host it as a gamescript language or, lately, implemented entirely in it.
- James_K 2y ago> C# instead, both with Unity and many other open or closed source engines, that either host it as a gamescript language or, lately, implemented entirely in it. And this is what confuses me. The opinions of game developers on this seems utterly baseless, and contradicted by the actual practice of the people who write game engines. I've only ever seen one (quite frankly genius) paper[1] on this that explores the question in a satisfying manner, and it suggests that garbage collection has something like a 17% overhead compared with a malloc call, at the cost of 3 times the memory usage. Not great, but it seems like a video game can afford to triple its memory usage given how it works with resources, and also given that a lot of what's allocated will be large assets which won't need to be counted in the 3× overhead since the represent a small number of objects compared to their size. [1] Matthew Hertz and Emery D. Berger. 2005. Quantifying the performance of garbage collection vs. explicit memory management. SIGPLAN Not. 40, 10 (October 2005), 313–326. https://doi.org/10.1145/1103845.1094836 https://doi.org/10.1145/1103845.1094836
- neonsunset 2y agoWhat do you mean by baseless? I strongly suggest to avoid such papers (unless they are recent and cover the impact of GC strategy as a whole vs how it is implemented) as they are likely to be worse than misleading, because in the area of memory management, a lot of performance lives and dies by implementation details. I tend to treat negatively such academic works because they become outdated fast, and are hard to draw conclusions from. Allocation in competent GC is explicitly cheaper (it's a 1-2 dereferences, and a pointer bump if allocation context/quantum/pool can satisfy the allocation without asking for more memory for the GC itself or without performing collection), you pay the cost later with mark and sweep, and pause time, but most of all, non-deterministic nature of "batch deallocation" of such kind.
- James_K 2y ago> What do you mean by baseless? They say "garbage collection is slow" and when I ask how they know, they have no response. > they are likely to be worse than misleading > they become outdated fast, and are hard to draw conclusions from. Out of interest, how many papers have you read and how have you come to these conclusions? What empirical evidence to you have for these claims? I don't dispute that there is a general lack of research around this area, but that hardly justifies discarding the scientific method. Given that many of them implement techniques which can simply be re-run as new runtimes are released, why do we not do this? With proper CI, you could easily keep this information as up-to-date as necessary. > Allocation in competent GC is explicitly cheaper I am well aware. When I say "allocation", I refer to the entire lifetime of an object. As in both its allocation, residence in memory, and cleanup. Did you read the paper I cited? It provides a strong case that this "lifetime-cost" of an object can be quantified and measured.
- neonsunset 2y ago> Did you read the paper I cited? It provides a strong case that this "lifetime-cost" of an object can be quantified and measured. I will read it in full, thanks.
- qwery 2y agoI'm sure part of it is just "conventional wisdom" at this point. I agree that you likely could design and implement an effective garbage collection-based memory allocator for game (engine) use cases. I am certain many successful titles have shipped with something you could call garbage collection. In my experience, the expected friction / hatred stems from the idea of a (language-level) GC that you as the developer have little to no control over. i.e. it's not about a direct performance cost/penalty so much as 1: a limiting factor or overhead (e.g. if you don't know which frame the penalty occurs you need to reserve time for it in every frame) and 2: the cost of dealing with yet another layer of main loop system synchronisation issues. The point about value types is relevant, but probably not strictly a GC issue, as you say. Fast value types are absolutely crucial to high performance game (engine) code. Value types to a game developer are stack-allocated. Going to the heap is completely out of the question. Here, "fast" means performance comparable to the basic numeric types.