Live data from Hacker News

For Better Computing, Liberate CPUs from Garbage Collection

spectrum.ieee.org

321–330 of 460 posts

Re: For Better Computing, Liberate CPUs from Garbage Collection

#321
post #303

Earlier quoted context omitted.

> Clearly somewhere in your code you have to explicitly handle tab closing and break the references to allow the GC to do its job. Why not free the resources here while you're at it? You are missing the point. The main point behind GC is removing the complexity of writing the software. Writing your own destructors, thinking about when to free your memory or writing lifetime annotations, needing to design your app in…

My point is that you need a "destructor" even with a GC. Continuing with my example you need to pop your tab from the data structure containing your tabs and you have to make sure that all references are dropped so that the GC will do its work. When I write Rust code I basically never have to explicitly free anything outside of FFI code dealing with C pointer or the like. The most straightforward way to allocate anyt…

> it's also important to recognize when something can't be pushed under the rug.

If you haven't heard of it, you might be interested in the Waterbed Theory of Complexity[1]. The idea behind it is that it's not that you can't push down complexity in an area, but often that complexity just pops up in a different area. For example, you can do away with the vast majority of allocating and freeing memory, but the complexity of doing that pops up again when you start having to tune your GC or use very special patterns to avoid/minimize GC freezes.

That's not to say there's not a benefit to that sometimes. If you can push the complexity away from the majority of use cases to a few special use cases, that might be a net win. It doesn't always feel like that though if you're the person stuck trying to coax that last few percent of performance optimizations out of a runtime that only gives you so many levers and dials to work with.

I think some of the same concerns that make a dynamic/scripting language a poor choice compared toa compiled and static one are the same things that might make a GC language a poor choice compared to a manually memory managed one, and it's just a matter of scale that separates them. Is performance important? A scripting language might be a poor choice. Is performance really important? Then a GC language might be a poor choice. On the other hand, if I'm writing some program to run correctly once or twice ever, and it might actually take more tome to write than it will ever run for (e.g. a script to parse and/or transform data on disk for me to fix a problem), then is anything really gained from manual memory management? Writing that in Perl or Bash is a valid option there, and that's about as far away from memory management as you can get. For portions of my career, I've spent half or more of my time writing programs like that to help with sysadmin tasks.

1: https://en.wikipedia.org/wiki/Waterbed_theory

Re: For Better Computing, Liberate CPUs from Garbage Collection

#322
post #257

Earlier quoted context omitted.

It's not at all zero CPU overhead, not even close. retain & release are thread-safe, meaning atomic ref count. Very comparable in cost to std::shared_ptr or Rust's Arc . Both of which also automatically insert the calls to inc & dec ref counts. It's cool that you don't need to bother with specifying the type as being std::shared_ptr or Arc , but it's not particularly novel, either. It's "just" syntax sugar (or lack o…

>retain & release are thread-safe That's optional tho, and I never use it that way.

Do you have a link to what you're referring to? Apple's docs clearly state retain/release are thread safe.

Are you using your own implementation of retain & release or something?

Re: For Better Computing, Liberate CPUs from Garbage Collection

#323
post #170

One talking point I'd like to ask is: For small short lived scripts and applications, do we even need to free any memory these days? For example you write a script which takes several seconds to execute, moves files, computes stuff with strings, etc. Should we really invest time and effort in the script interpreter to free the memory, where instead we can just exit normally and let the OS handle the clean up. I would…

> For small short lived scripts and applications, do we even need to free any memory these days? ..we can just exit normally and let the OS handle the clean up. That makes me think: why couldn't larger programs be composed of many such small, short-lived scripts/processes that give up all allocated memory upon exit? I suppose there could be accumulated overhead for starting many such processes, and also the issue of…

This is basically the actor model. (many processes, sharing immutable data between them).

Re: For Better Computing, Liberate CPUs from Garbage Collection

#324
post #306

Earlier quoted context omitted.

>Rust features a lot of "cheating" - pointers that allow mutation from multiple threads You're confounding GC and synchronization of multi-threaded access here. What rust does with things like Arc other languages will need some other synchronization primitive to enable. Their GC or manual memory management does not guarantee the multi-threaded semantics. That's one of the advantages of the rust memory model, some pat…

No, Rust is conflating memory safery and multithreading safety. JVM state-of-the-art GC guarantees multithreaded memory safety. AFAIK many wait-free data structures are pretty much impossible without a GC.

You start your response with "No" but don't actually argue against anything I've said.

> Rust is conflating memory safery and multithreading safety.

Rust doesn't conflate anything. It just gets some multi-threading safety for free as a result of its memory model. And then gets quite a few other multi-threading safety characteristics that no other mainstream language has from the type system. That several features in the language work together well is just a sign of good design.

> JVM state-of-the-art GC guarantees multithreaded memory safety.

This is where you're mixing the two unrelated concepts. Garbage collection does nothing for multi-threading safety. While the object is live and two threads hold a reference to it you need to synchronize access somehow. GC can't do anything about that.

> AFAIK many wait-free data structures are pretty much impossible without a GC.

This is unrelated to the previous points I made but isn't true either:

https://aturon.github.io/blog/2015/08/27/epoch/

Re: For Better Computing, Liberate CPUs from Garbage Collection

#325
post #238

Earlier quoted context omitted.

You came in guns blazing and then covered yourself in embarrassment already in the first two points you made. The thing you said doesn't work is in use on millions of devices, working just fine. Or maybe you'd like to be more precise than "work". Avoiding cycles and thinking about ownership is not programming carefully, it's merely programming. Really, manual memory management is not rocket science folks, just error…

> Really, manual memory management is not rocket science folks, just error prone Doesn't have to be rocket science to be a cognitive burden. And we want to eliminate "error prone" factors...

And we did eliminate them.

But no one can seriously claim that GC is a magic bullet, because it's only clearly winning against plain C.

Carefully designed, popular languages are choosing RAII and reference counting implementations and those are very competitive.

Re: For Better Computing, Liberate CPUs from Garbage Collection

#326
post #267

Earlier quoted context omitted.

Ridiculous. The problem is not that you don't know when/where the lifetime will end — that can usually be characterized by a terse "English" description. The problem is that this lifetime is dynamic in nature. The end of the lifetime of an object may coincide with some user input, for instance. At this point, either you go back to manual management, with the potential for errors (and for what it's worth, I think manu…

I don't see your point. Of course sometimes the lifetime of an object is not tied to code scope but actually to something dynamic. Let's say for instance when you close a tab in your browser you expect the resources to be freed (ignoring caching to simplify the argument). Clearly somewhere in your code you have to explicitly handle tab closing and break the references to allow the GC to do its job. Why not free the r…

> When you say "manual memory management" if you're thinking C-style malloc-free then you have a point, it's very easy to forget a free() somewhere. But any language with destructors can handle these situations without much more overhead than GC-based approaches.

What happens when that object is shared and still referenced from somewhere else? Now you have a use after free error waiting to happen.

Re: For Better Computing, Liberate CPUs from Garbage Collection

#327

Earlier quoted context omitted.

You say > but it was a false dichotomy: We can have memory safety without garbage collection. but then say > Automatic reference counting (ARC henceforth). Naive ARC is AFAIK very expensive as it causes a lot of updates at each pointer 'take' even if it's a read only (chasing pointers), trashing caches. Poss. even worse if multithreading is used as a memory barrier may have to be issued. Also it does not collect cycl…

> Naive ARC is AFAIK very expensive as it causes a lot of updates It also means you can't really rely on CoW after fork(). After a while your whole heap will be duplicated in every process because of the RC updates.

A simple trick gets you around this: Don't use your system malloc() but instead map a tempfile (or a memfd) with MAP_SHARED and use the STM primitives to update your references. If you combine this trick with __attribute__((address_space(256))) your "pointers" are also the offsets in the tempfile.

Or don't: Maybe you want two heaps. fork() gives you the option!

Re: For Better Computing, Liberate CPUs from Garbage Collection

#328
post #306

Earlier quoted context omitted.

No, Rust is conflating memory safery and multithreading safety. JVM state-of-the-art GC guarantees multithreaded memory safety. AFAIK many wait-free data structures are pretty much impossible without a GC.

You start your response with "No" but don't actually argue against anything I've said. > Rust is conflating memory safery and multithreading safety. Rust doesn't conflate anything. It just gets some multi-threading safety for free as a result of its memory model. And then gets quite a few other multi-threading safety characteristics that no other mainstream language has from the type system. That several features in…

By "conflating" I mean that Rust's memory management technology provides just one kind of multi-threading safety (i.e. "multiple readers/single-writer" model), but to implement other kinds of multi-threading-safe algorithms/data structures, you need to transcend beyond ownership+borrowing.

I think "epoch-based memory reclamation" (which Linux kernel also uses IIRC) is still a (primitive / limited / contained) form of GC. For those that aren't familiar with it, a quote from the article @pedrocr posted:

> The basic idea is to stash away nodes that have been unlinked from the data structure (the first source of reachability) until they can be safely deleted. Before we can delete a stashed node, we need to know that all threads that were accessing the data structure at the time have finished the operation they were performing.

So basically, the runtime needs to keep track of allocated objects until it's certain there are no more references to them... sounds like GC (the difference between this and a real GC is that (1) you know there's no cross-references between the nodes, so you don't need to mark&sweep but just need to keep track of the epoch, and (2) the nature of lock-free data structures is such that threads will move to the next epoch fairly soon (unless they infinite-loop)).

Re: For Better Computing, Liberate CPUs from Garbage Collection

#329

IMO garbage collection is the epitome of sunk cost fallacy. Thirty years of good research thrown at a bad idea. The reality is we as developers choose not to give languages enough context to accurately infer the lifetime of objects. Instead of doing so we develop borderline self-aware programs to guess when we're done with objects. It wastes time, it wastes space, it wastes energy. If we'd spent that time developing…

Cyclic data structures, memory safety, memory management without tracing. Pick 2.

Re: For Better Computing, Liberate CPUs from Garbage Collection

#330

IMO garbage collection is the epitome of sunk cost fallacy. Thirty years of good research thrown at a bad idea. The reality is we as developers choose not to give languages enough context to accurately infer the lifetime of objects. Instead of doing so we develop borderline self-aware programs to guess when we're done with objects. It wastes time, it wastes space, it wastes energy. If we'd spent that time developing…

You seriously should just start the discussion by actually checking out how garbage collection actually works instead of touting random garbage about how it is just a predictions game.

Garbage collection has multiple variations, multiple optimizations, multiple tradeoffs. Different variations are powering the most popular and the most used languages all around the world (see also: C#, Javascript, Java).

To think that that is just "research thrown at a bad problem" is sheer insanity.

I propose we split this discussion up, because dealing with leaks is a completely different problem than dealing with garbage collection. You can have memory leaks in manually managed languages too, it has nothing to do with GC. But lets not throw the whole field out just because you do not want to deal with automatic memory management tradeoffs.

Post reply on HN