Live data from Hacker News

The Garbage Collection Handbook: The Art of Automatic Memory Management (2nd Ed) (2023)

gchandbook.org

61–64 of 64 posts

Re: The Garbage Collection Handbook: The Art of Automatic Memory Management (2nd Ed) (2023)

#61
post #46

Earlier quoted context omitted.

> But that doesn't mean any language that allows you to implement reference counting as a library, is a garbage-collected language. The concept of "a garbage-collected language" is not well-defined. There are languages, like Java, Rust, and Python that depend on a garbage collection mechanism, and languages like C, C++ and Zig, which don't. C++ happens to offer a GC in its standard library, however. That "working dev…

> The concept of "a garbage-collected language" is not well-defined. There are languages, like Java, Rust, and Python that depend on a garbage collection mechanism, and languages like C, C++ and Zig, which don't. C++ happens to offer a GC in its standard library, however. How does Rust differ from C++ in this regard? As far as I know, both use RAII, and offer something RC-like in their stdlib that is optional to use.

If we view Rust (including unsafe) as a memory-unsafe language, then it's the same as C++, since we can then view Rc/Arc as optional. But if we want to look at Rust as a memory-safe language, then it mandates the use of GC when an object may have multiple owners. In other words, Rust depends on GC to ensure the memory safety of common functionality. It is true that Java depends on GC for even more operations, but the fact remains that it's very hard to write many large Rust programs without the use of the GC in its runtime (unless you go unsafe, in which case it's like C++, where the GC is optional).

I think many people, especially those with insufficient experience with both low-level languages and modern garbage collectors incorrectly assume that the presence or reliance on GC necessarily implies some performance overhead. In actuality, some GCs (moving GCs in particular) were invented, among other reasons, to reduce the overhead imposed by malloc/free that causes significant performance problems in large programs written in low-level languages. Of course, refcounting GCs, as well as some tracing GCs (non-moving ones) also rely on malloc/free, so they may still suffer from the same issues.

Another misconception is that "a GC" is some necessarily large and sophisticated runtime mechanism compared to "no GC". The problem with that view is that modern malloc/free are also large and elaborate runtime mechanisms (in the range of 10KLOC), and they're elaborate because clever sophistication, as well as CPU/footprint tradeoffs, are required to get decent performance from such allocators (another fact that experienced low-level programmers know). Modern malloc/free allocators may be larger and more complex than simple moving collectors (although it is true that modern moving collectors are larger and more complex than modern malloc/free allocators, but they both require non-trivial runtimes).

Re: The Garbage Collection Handbook: The Art of Automatic Memory Management (2nd Ed) (2023)

#62
post #60

Earlier quoted context omitted.

> where the programmer is responsible for invoking "free", was a serious mistake and it was an obsolete technique already at the date of its introduction. It wasn’t obsolete then nor now. Garbage collected languages, to this day, still use on average about 2x-5x the working memory of carefully written manual memory programs. A significant amount of devices then and even today cannot support such sloppy use of resourc…

I think they mean something more akin to RAII in C++/rust. Manually writing a free statement is very error-prone and there are better language-level features to avoid that.

RAII has nothing to do with garbage collection. It only provides a way to get a resource somewhat atomically. If the creator doesn’t delete the object, or if the object has a malformed destructor, it fails. If the creator calls delete twice, it fails. There’s really no garbage collection at all here.

Re: The Garbage Collection Handbook: The Art of Automatic Memory Management (2nd Ed) (2023)

#63

Earlier quoted context omitted.

In my opinion, the "manual" memory management, introduced by the IBM PL/I programming language by the end of 1964, and inherited by C and other languages, i.e. where the programmer is responsible for invoking "free", was a serious mistake and it was an obsolete technique already at the date of its introduction. When the explicit "free" was invented, automatic memory reclamation while avoiding the non-determinism of g…

> where the programmer is responsible for invoking "free", was a serious mistake and it was an obsolete technique already at the date of its introduction. It wasn’t obsolete then nor now. Garbage collected languages, to this day, still use on average about 2x-5x the working memory of carefully written manual memory programs. A significant amount of devices then and even today cannot support such sloppy use of resourc…

Is there a scheme where memory is auto-freed if it goes out of scope?

If so, are there benefits/drawbacks to that?

Re: The Garbage Collection Handbook: The Art of Automatic Memory Management (2nd Ed) (2023)

#64

Earlier quoted context omitted.

> where the programmer is responsible for invoking "free", was a serious mistake and it was an obsolete technique already at the date of its introduction. It wasn’t obsolete then nor now. Garbage collected languages, to this day, still use on average about 2x-5x the working memory of carefully written manual memory programs. A significant amount of devices then and even today cannot support such sloppy use of resourc…

Is there a scheme where memory is auto-freed if it goes out of scope? If so, are there benefits/drawbacks to that?

If it's on the stack, it's almost free to do.

If it's held by a unique_ptr, then it auto frees, but there is a lot of programmer work to ensure things behave well, and there are nuances to allocating something into the unique_ptr.

If it's a std::shared_ptr, which is the closest to what people think of, it's then a reference counted object, which requires a little more storage, and also has the ability to be mishandled as a pointer, screwing it up, or making the wrong type of copy of the shared_ptr, so two there are two things, and also fails to release object in the case of circluar references.

Then there's a lot of other subtle things you can do, and none of this is as lightweight as a pointer, and none is as automatic as what most people think of as garbage collection.

And each has costs and tradeoffs, which is why C++ added them: making certain tradeoffs easier to use, but it requires solid understanding of how such things work.

Post reply on HN