Live data from Hacker News

Garbage collection for Rust: The finalizer frontier

soft-dev.org

161–170 of 184 posts

Re: Garbage collection for Rust: The finalizer frontier

#161
post #157
post #154

Earlier quoted context omitted.

Go I agree, .NET is on par with JVM, even if they don't have the pleothora of choice regarding JVM implementations, and the ability to do C++ like coding means there isn't that much of a pressure for pauseless GC as in Java. Looking forward to Project Valhalla updates, I had some fun with the first EA.

I'm not sure what is meant here by "on par with the JVM." I'm not trying to claim that one or the other is better, but there is a basic difference in how they're designed and continue to evolve. .NET believes in a language that gives more control on top of a more basic runtime, while Java believes in a language that's smaller built on top of a more advanced runtime. They just make different tradeoffs. .NET doesn't "n…

It means that it does the same JIT optimization tricks that Hotspot performs, escape analysis, devirtualization, inlining method calls, removing marshaling layers when calling into native code, PGO feedback,....

I would like to someday have someone write blog posts about performance like the famous ones from the .NET team, and also not having to depend on something external like JIT Watch, instead of having it in box like .NET.

Example for upcoming .NET 10,

https://devblogs.microsoft.com/dotnet/performance-improvemen...

Also C# and .NET low level programming features are here today, Project Valhala delivery is still in future, to be done across several versions, assuming that Oracle's management doesn't lose interest funding the effort after all these years.

It is kind of interesting how after all these years, the solution is going to be similar in spirit to what Eiffel expanded types were already offering in 1986.

https://wiki.liberty-eiffel.org/index.php/Expanded_or_refere...

https://archive.eiffel.com/doc/online/eiffel50/intro/languag...

I guess that is what happens when language adoption turns out to go in a different path than originally planned, given Java's origins.

Re: Garbage collection for Rust: The finalizer frontier

#162
post #126

Earlier quoted context omitted.

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…

The popular Bumpalo only returns references with the lifetime of the allocator. Not sure what you mean by manage your own garbage, an arena allocator deallocates everything when it goes out of scope. You definitely can't reference uninitialized parts of an arena.

Re: Garbage collection for Rust: The finalizer frontier

#163
post #161
post #157

Earlier quoted context omitted.

I'm not sure what is meant here by "on par with the JVM." I'm not trying to claim that one or the other is better, but there is a basic difference in how they're designed and continue to evolve. .NET believes in a language that gives more control on top of a more basic runtime, while Java believes in a language that's smaller built on top of a more advanced runtime. They just make different tradeoffs. .NET doesn't "n…

It means that it does the same JIT optimization tricks that Hotspot performs, escape analysis, devirtualization, inlining method calls, removing marshaling layers when calling into native code, PGO feedback,.... I would like to someday have someone write blog posts about performance like the famous ones from the .NET team, and also not having to depend on something external like JIT Watch, instead of having it in box…

> It means that it does the same JIT optimization tricks that Hotspot performs, escape analysis, devirtualization, inlining method calls, removing marshaling layers when calling into native code, PGO feedback,....

It has rather recently started using most (or perhaps all) of the same techniques; it does not actually perform all the same optimisations. C2 is still significantly more advanced. Of course, some optimisations are more difficult in C#, as its "low level" features expose more implementation details, giving the compiler less freedom.

> It is kind of interesting how after all these years, the solution is going to be similar in spirit to what Eiffel expanded types were already offering in 1986.

I don't have time to compare the details (and I don't work on Valhalla), but it doesn't seem to me to be the same thing. In Eiffel, the class says whether or not it's expanded. In Java, the compiler decides, as an optimisation, whether to inline or box different object instances (on a per-object, not per-class basis). It's just that classes with certain characteristics give the compiler more freedom to inline in more cases.

Think about it this way: In Java 8, Integer and int are two different types with very different behaviours, albeit with an autoboxing relationship. You can't synchronize on an int instance or assign null to an int variable; equality comparisons on Integer compare object identity, not numeric value. We'll gradually turn Integer and int into effectively the same type (with two names, for historical reasons), and turn the decision of whether a particular instance is inlined or not up to the compiler, as an optimisation decision. It's not that autoboxing will expand to user defined types, but rather it will become nonexistent.

But generally, almost anything we do in Java is something that's been done (more or less) somewhere else a while ago, because we like to avoid ideas that have not been tested. Basically, for X to be considered for Java, there must exist some language that tried X in 1986. It's just that it's not always the same language.

Re: Garbage collection for Rust: The finalizer frontier

#164

Earlier quoted context omitted.

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.

When you have a strong pointer, you already have a positive ref count. Only once the strong pointer is destructed, is the reference count decremented.

Re: Garbage collection for Rust: The finalizer frontier

#165
post #117

Earlier quoted context omitted.

This sounds more like "this is what I like in rust" than "features any modern language should have" though If you like rust, use rust. It's very likely the best rust

> This sounds more like "this is what I like in rust" than "features any modern language should have" though Good build tooling has been around since 2004, and all of the rest of those features have been around since the late 1970s. There's really no excuse for a language not having all of them.

Every language should have haskell level pattern matching?

Re: Garbage collection for Rust: The finalizer frontier

#166
post #44

> Having acknowledged that pointers can be 'disguised' as integers, it is then inevitable that Alloy must be a conservative GC C# / dotnet don't have this issue. The few times I've needed a raw pointer to an object, first I had to pin it, and then I had to make sure that I kept a live reference to the object while native code had its pointer. This is "easier done than said" because most of the time it's passing strin…

A Gc that can't give you a pointer inside seems almost unusable in the context of Rust. Pointers are not a narrow use case; references are pointers.

Rust APIs are largely built around references. If you were to put a Vec (dynamic array) into a pointerless Gc, you would be almost entirely unable to access its contents. The only way to access it would be swap it with an empty Vec, access it, then swap it back a-la Cell. You wouldn't even be able to clone the Vec without storing a dummy version in its place during the call.

https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#m...

Re: Garbage collection for Rust: The finalizer frontier

#167
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.

It's possible to turn off GC for most of go and only use it where I want it? That's what this solution gives us for Rust.

Re: Garbage collection for Rust: The finalizer frontier

#168
post #44

> Having acknowledged that pointers can be 'disguised' as integers, it is then inevitable that Alloy must be a conservative GC C# / dotnet don't have this issue. The few times I've needed a raw pointer to an object, first I had to pin it, and then I had to make sure that I kept a live reference to the object while native code had its pointer. This is "easier done than said" because most of the time it's passing strin…

Worse, conservatism in a GC further implies it can't be a moving GC, which means you can't compact, use bump pointer allocation, and so on. It keeps you permanently behind the frontier. I remain bitterly disappointed that so much of the industry is so ignorant of the advances of the past 20 years. It's like it's 1950 and people are still debating whether their cloth and wood airplanes should be biplanes or triplanes.

Yea, but, this is Rust. How is a moving GC supposed to handle an untagged union? Or a person who uses the now-stable provenance api to read/write pointer bits to/from disk.

Re: Garbage collection for Rust: The finalizer frontier

#169
post #68
post #50

Earlier quoted context omitted.

Maybe I picked the wrong wording--I don't mean to diminish the ambitions or scope of Valhalla--but I definitely think the decision to eschew value types at the start has immense bearing on the difficulty of adding them now. Java's major competitors, C# and Go, both have had value types since day one and reified generics since they gained generics; this hasn't posed any major problems to either language (with the form…

> Java's major competitors, C# and Go, both have had value types since day one Yes (well, structs; not really value types), but at a significant cost to FFI and/or GC and/or user-mode threads (due to pointers into the stack and/or middle of objects). Java would not have implemented value types in this way, and doing it the way we want to would have been equally tricky had it been done in Java 1.0. Reified generics al…

This has been a very informative discussion, so thank you for that.

I did want to point out, though, that both languages have other (compound) value types than just structs. Go has value-based arrays, and C# has value-based tuples. It looks like C# may gain value-based discriminated unions as well, though it's not settled yet: https://github.com/dotnet/csharplang/blob/main/proposals/uni...

Re: Garbage collection for Rust: The finalizer frontier

#170

Earlier quoted context omitted.

Also, the proposed garbage collector is still opt in. Only pointers that are specifically marked as GC are garbage collected. This means that most references are still cleaned up automatically when the owner goes out of scope. This greatly reduces the cost of GC compared to making all heap allocations garbage collected. This isn't even a new concept in Rust. Rust already has a well accepted RC type for reference coun…

Language where most of the libraries are without GC, but has an GC opt in would be interesting. For example only your business logic code would use GC (so you can write it more quickly). And parts where you don't want GC are still written in the same language, avoiding the complexity of FFI. Add opt-in development compilation JIT for quick iteration and you don't need any other language. (Except for user scripts wher…

The D programming language has an optional garbage collector. [0][1]

With the @nogc attribute the compiler can check/enforce that your function doesn't depend on the GC. [2]

[0] https://dlang.org/spec/garbage.html

[1] https://news.ycombinator.com/item?id=33382159

[2] https://dlang.org/spec/function.html#nogc-functions

Post reply on HN