Borrow Checking, RC, GC, and the Eleven () Other Memory Safety Approaches

todsacerdoti | 189 points

I think it’s better to view reference counting and gc as two kinds of garbage collection: https://courses.cs.washington.edu/courses/cse590p/05au/p50-b...

fiddlerwoaroof | 14 days ago

Never free and periodically crashing by OOM killer is rarely used but can be useful in limited circumstances. There are some shops that arbitrarily kill any worker over X hours old under the hypothesis that a memory leak is present or probably present.

hi-v-rocknroll | 14 days ago

Best part

>I was once working with a customer who was producing on-board software for a missile. In my analysis of the code, I pointed out that they had a number of problems with storage leaks. Imagine my surprise when the customers chief software engineer said "Of course it leaks". He went on to point out that they had calculated the amount of memory the application would leak in the total possible flight time for the missile and then doubled that number. They added this much additional memory to the hardware to "support" the leaks. Since the missile will explode when it hits its target or at the end of its flight, the ultimate in garbage collection is performed without programmer intervention.

kernal | 14 days ago

> "Linear reference counting is an elusive concept, where we can completely eliminate the counter integer, and do all of the reference counting at compile time."

Right. I've occasionally thought about that for Rust, as a way to do back references. You can have an Rc owning an object, which can own another object, which can have a weak RC reference back to the original. This allows you to find an object's owner when needed, so you can do inheritance-like things when you need to. The single-ownership and dangling-pointer checks are made at run time and will panic if they fail.

Now, the question is, can you statically check access behavior and determine that those panics will never occur? If you can, you can eliminate the reference counts and checks. That looks 1) possible, and 2) a PhD thesis sized problem.

Animats | 14 days ago

It's weird to see no mention in this post of separation logic, which would seem to provide a basic, general foundation for most of these techniques if perhaps not all of them. For instance, the RustBelt paper gives a description of Rust borrow checking that can arguably be understood as relying on some form of separation logic.

zozbot234 | 14 days ago

I am surprised that call stacks aren't mentioned. The call stack is a great way to free up memory that's no longer being used by a function. Maybe it was too obvious to include?

habitue | 14 days ago

Most of the fancier runtime-less non-GC techniques fail when it comes to graph data structures (or even linked lists) without a tremendous amount of upfront work from the programmer.

KRAKRISMOTT | 14 days ago

> And as it turns out, reference counting can be blended with immutable region borrowing to greatly reduce its cache misses and make it data-race safe, something no language has done yet.

Rust prevents data races, so I'm not sure what this is referring to.

kibwen | 14 days ago

Isn't the "regions" approach similar/same in principle, as Rust's memory model?

A region's model is described as:

> Pony's iso keyword: an iso'd object (and its contents) are only reachable from your pointer; nobody else points at that object or anything the object contains [...] we can "temporarily open" an isolated subgraph for a given scope, and afterward it would still be properly isolated.

In Rust, AFAIR, one gets a mutable reference to an object, and the borrower can independently operate on its fields (subgraphs), while the root mutable reference can't be accessed from anything else other than the borrower.

pizza234 | 14 days ago

Early Fortran worked in a way that every function was allocated a global static memory area for its arguments, variables and the result. No stack, no heap, no worries.

EVa5I7bHFq9mnYK | 14 days ago

A compile-time reference counting and reference count ellision scheme would be awesome for jq. It could only happen with an escape hatch to reference counting. We had an interesting contribution that added a piece of this, but meant for libjq-using applications, not for jq itself.

cryptonector | 14 days ago

The language the development of which this blog discusses is worth checking out too: https://www.uiua.org

It is an interesting APL successor I was planning to learn after getting current projects out of the way.

neonsunset | 14 days ago
[deleted]
| 15 days ago

Java supports the never free strategy with Epsilon GC

EricRiese | 14 days ago

TFA is pretty awesome, not least because of all the links. I'm going to be reading for a while.

cryptonector | 14 days ago

what about "self freeing" pointers?

you allocate and must / are extending its lifetime all the time or else it frees itself! very predictable behaviour of memory collection.

you get pointer and keep it allocated by "extending" its lifecycle.

kovacs_x | 14 days ago
[deleted]
| 14 days ago

This is interesting but exhausting to read. I get the joke but come on, after the first few of these can I just read the information in line.

MarkMarine | 14 days ago
[deleted]
| 14 days ago