Live data from Hacker News

Garbage collection for Rust: The finalizer frontier

soft-dev.org

121–130 of 184 posts

Re: Garbage collection for Rust: The finalizer frontier

#121
post #13

Earlier quoted context omitted.

Oh no, I'm directly criticizing C/C++/Java/C#: The heavyweight framework (and startup cost) that comes with Java and C# makes them challenging for widely-adopted lightweight command-line tools. (Although I love C# as a language, I find the Rust toolchain much simpler and easier to work with than modern dotnet.) Building C (and C++) is often a nightmare.

New AOT C# is nice, but not fully doable with the most common dependencies. It addresses a lot of the old issues (size, bloat, startup latency, etc)

Hilariously, the Microsoft SQL Client is the primary blocker for AOT for most potential usecases.

Want fast startup for an Azure Function talking to Azure SQL Database? Hah… no.

In all seriousness, that one dependency is the chain around the ankle of modern .NET because it’s not even fully async capable! It’s had critical performance regression bugs open for years.

Microsoft’s best engineers are busy partying in the AI pool and forgot about drudgery like “make the basics components work”.

Re: Garbage collection for Rust: The finalizer frontier

#122
post #5

Before making criticisms that Garbage Collection "defeats the point" of Rust, it's important to consider that Rust has many other strengths: - Rust has no overhead from a "framework" - Rust programs start up quickly - The rust ecosystem makes it very easy to compile a command-line tool without lots of fluff - The strict nature of the language helps guide the programmer to write bug-free code. In short: There's a lot…

Aren't Rust programs still considerably larger than their C equivalent because everything is statically linked? It's kind of hard to see that as an advantage.

Re: Garbage collection for Rust: The finalizer frontier

#123

Earlier quoted context omitted.

> The heavyweight framework Do you mean the VM/runtime? If so, you might be able to eliminate that with an AOT build. > I find the Rust toolchain much simpler and easier to work with than modern dotnet What part of the toolchain? I find them pretty similar with the only difference being the way you install them (with dotnet coming from a distro package and Rust from rustup)

Exactly, natively compiled garbage collected languages (like Java with Graal; or as executed on Android) don't have a lot of startup overhead. In Java the startup overhead is mostly two things that usually conspire to make things worse: 1) dynamic loading of jar files 2) reflection Number 1 allows you to load arbitrary jar files with code and execute them. Number 2 allows you to programmatically introspect existing c…

You forgot to mention Quarkus :)

Re: Garbage collection for Rust: The finalizer frontier

#124
post #67

Earlier quoted context omitted.

Swift uses reference counting Slows down every access to objects as reference counts must be maintained Something weird that I never bothered with to enable circular references

Reference counted pointers can deference an object (via a strong pointer) without checking the reference count. The reference count is accessed only on operations like clone, destruction, and such. That being said, access via a weak pointer does require a reference count check.

This sounds different from common refcounting semantics in other languages, is it really so in Swift?

Usually access increases the reference count (to avoid the object getting GC'd while you use it) and weak pointers are the exception where you are prepared for the object reference to suddenly become invalid.

Re: Garbage collection for Rust: The finalizer frontier

#125
post #70

I have thought for years Rust needs to bifurcate. Asyc/await really desperately needs a garbage collector. (See this talk from Rustconf 2025: https://youtu.be/zrv5Cy1R7r4?si=lfTGLdJOGw81bvpu and this blog: https://rfd.shared.oxide.computer/rfd/400 ) Rust that uses standard techniques for asynchronous code, or is synchronous, does not. Async/await sucks all the oxygen from asynchronous Rust Async/await Rust is a diffe…

Hi -- I'm the one who presented the talk -- honored! I'm curious how you got to "async Rust needs a [tracing] garbage collector" in particular. While it's true that a lot of the issues here are downstream of futures being passive (which in turn is downstream of wanting async to work on embedded), I'm not sure active futures need a tracing GC. Seems to me like Arc or even a borrow-based approach would work, as long as…

My comment is quite general.

The difficulties with async/await seem to me to be with the fact that code execution starts and stops using "mysterious magic", and it is very hard for the compiler to know what is in, and what is out, of scope.

I am by no means an expert on async/await, but I have programmed asynchronously for decades. I tried using async/await in Rust, Typescript and Dart. In Typescript and Dart I just forget about memory and I pretend I am programming synchronously. Managed memory, runtimes, money in the bank, who is complaining? Not me.

\digression{start} This is where the first problem I had with async/await cropped up. I do not like things that are one thing, and pretend to be another - personally or professionally - and async/await is all about (it seems to me) making asynchronous programming look synchronous. Not only do I not get the point - why? is asynchronous programming hard? - but I find it offensive. That is a personal quibble and not one I expect many others to find convincing I guess I am complaining.... \digression{end}

In Rust I swiftly found myself jumping through hoops, and having to add lots and lots of "magic incantations" none of which I needed in the other languages. It has been a while, and I have blotted out the details.

Having to keep a piece of memory in scope when the scope itself is not in my control made me dizzy. I have not gone back and used async/await but I have done a lot of asynchronous rust programming since, and I will be doing more.

My push for Rust to bifurcate and become two languages is because async/await has sucked up all the oxygen. Definitely from asynchronous Rust programming, but it has wrecked the culture generally. The first thing I do when I evaluate a new crate is to look for "tokio" in the dependencies - and two out of three times I find it. People are using async/await by default.

That is OK, for another language. But Rust, as it stands, is the wrong choice for most of those things. I am using it for real time audio processing and it is the right choice for that. But (e.g) for the IoT lighting controller [tapo](https://github.com/mihai-dinculescu/tapo) it really is not.

I am resigned to my Cassandra role here. People like your good self (much respect for your fascinating talk, much envy for your exciting job) are going to keep trying to make it work. I think it will fail. It is too hard to manage memory like Rust does with a borrow checker with a runtime that inserts and runs code outside the programmer's control. There is a conflict there, and a lot of water is going under the bridge and money down the drain before people agree with me and do what I say...

Either that or I will be proved wrong

Lastly I have to head off one of the most common, and disturbing, counter (non) arguments: I absolutely do not accept that "so many smart people are using it it must be OK". Many smart people do all sorts of crazy things. I am old enough to have done some really crazy things that I do not like to recall, and anyway, explain Windows - smart people doing stupid things if ever

Re: Garbage collection for Rust: The finalizer frontier

#126
post #72

Earlier quoted context omitted.

> works well with borrow checking. Yes, because it defeats borrow checking. Unsafe Rust, used directly, works too

It does not defeat borrow checking. The borrow checker will ensure that objects do not outlive the arena. It works with borrow checking.

The borrow checker knows nothing about your arena allocations.

That is if we are talking about the same thing!

All the borrow checker knows is there is a chunk of memory (the arena) in scope.

It works, no memory safety in the sense that you must manage your own garbage and you can reference uninitialized parts of the arena

I have found myself using arenas in Rust for managing circular references (networks with cycles) and if I were to do it again I think I would write that bit in C or unsafe Rust.

Re: Garbage collection for Rust: The finalizer frontier

#127
post #33

Earlier quoted context omitted.

In all honesty, there are three topics I try to refrain myself from engaging with on HN, often unsuccesfully: politics, religion, and rust. I don't know what you had to go through before reaching rust's secure haven, but what you just said is true for the vast majority of compiled languages, which are legions.

It's the fledging of a new generation of developers. Every time I see one of these threads I tell myself, "you, too, were once this ignorant and obnoxious". I don't know any cute except letting them get it out of their system and holding my nose as they do.

Well you might find it good to learn that Rust is based on plenty of ideas dating back decades, so _your_ obnoxious and patronizing attitude is unwarranted.

Re: Garbage collection for Rust: The finalizer frontier

#128
post #35
post #5

Before making criticisms that Garbage Collection "defeats the point" of Rust, it's important to consider that Rust has many other strengths: - Rust has no overhead from a "framework" - Rust programs start up quickly - The rust ecosystem makes it very easy to compile a command-line tool without lots of fluff - The strict nature of the language helps guide the programmer to write bug-free code. In short: There's a lot…

Go is probably a better pick in this case.

With data intensive Go applications you eventually hit a point where your code has performance bottlenecks that you cannot fix without either requiring insane levels of knowledge on how Go works under the hood, or using CGo and incurring a high cost for each CGo call (last I heard it was something like 90ns), at which point you find yourself regretting you didn't write the program in Rust. If GC in Rust could be made ergonomic enough, I think it could be a better default choice than Go for writing a compiled app with high velocity. You could start off with an ergonomic GC style of Rust, then later drop into manual mode wherever you need performance.

Re: Garbage collection for Rust: The finalizer frontier

#129
post #71

Earlier quoted context omitted.

Testing on my machine, Hello World in java (openjdk 21) takes about 30ms. In contrast, "time" reports that rust takes 1ms, which is the limit of it's precision. Python does Hello World in just 8ms, despite not having a separate AOT compilation step. The general guidance I've seen for interaction is that things start to feel laggy at 100ms; so 30ms isn't a dealbreaker, but throwing a third of your time budget at the b…

I'm trying and failing to imagine a situation where 30ms startup time would be a problem. Maybe some kind of network service that needs to execute a separate process on every request?

It's not about how long someone is willing to wait with a timer and judge it on human timescales, it's about what is an appropriate length of time for the task.

30ms for a program to start, print hello world, and terminate on a modern computer is batshit insane, and it's crazy how many programmers have completely lost sight of even the principle of this.

Re: Garbage collection for Rust: The finalizer frontier

#130

Earlier quoted context omitted.

It's the fledging of a new generation of developers. Every time I see one of these threads I tell myself, "you, too, were once this ignorant and obnoxious". I don't know any cute except letting them get it out of their system and holding my nose as they do.

Well you might find it good to learn that Rust is based on plenty of ideas dating back decades, so _your_ obnoxious and patronizing attitude is unwarranted.

Rust gets some things right and some things wrong. Its designers are generally clueful, but like all humans, fallible. But what does this discussion have to do with Rust exactly? Exactly the same considerations would apply to a C++ GC.

The only thing more cringe than insisting on a GC strategy without understanding the landscape is to interpret everything as an attack on one's favored language.

Post reply on HN