Live data from Hacker News

Rust Memory Management: Ownership vs. Reference Counting

slicker.me

41–50 of 54 posts

Re: Rust Memory Management: Ownership vs. Reference Counting

#41

I've not really used Rust, and I can certainly appreciate the goal of the language. However this code bothers me, and I can't really articulate why. struct Node { value: i32, children: Vec >>>, parent: Option >>>, // Weak breaks parent→child cycle } I understand its all boxes inside boxes inside boxes, but as an outsider it looks confusing mixing data type semantics with memory managment semantics.

I see beginners trip over themselves when they get obsessed with allocation (never mind they're coming from like, Python) but in a language like Rust (or C++) you are writing programs with the intent to control how memory is managed. So it makes a lot of sense to tie memory to the types as a part of their semantics.

It's not without problems, but the idea is less confusing in practice than it seems.

Re: Rust Memory Management: Ownership vs. Reference Counting

#42
post #13

Earlier quoted context omitted.

I am not familiar with scene graphs, but what is the problem with borrowing or refcounting? This article showed how you can have multiple mutable references in Rust, even multiple mutable references running in parallel threads.

Ref counting is for ownership, it doesnt convey intent. It kind of accidently works but is the wrong abstraction, especially in code bases where ownership is known.

If you're building data structures that have specific requirements and you know you'll implement it correctly, you can use raw pointers like `*mut T`. That's why they're in the language, for when you need to do something that the borrow checker can't verify and don't want the overhead of runtime borrow checks.

Re: Rust Memory Management: Ownership vs. Reference Counting

#43
post #15

Earlier quoted context omitted.

> without a garbage collector, that's the novel part? That's not quite how it works in various languages. You appear to be thinking of the garbage collector as something inseparable from the language. Both Dlang and Vlang have optional garbage collectors, that can be turned off. In the case of Vlang, none of its libraries depend on the garbage collector. Vlang offers optional (flexible) memory management, somewhat si…

The moment you turn on garbage collection in Dlang, you've introduced stop the world pauses to all your Dlang threads. If you were to implement a Rust GC, then Rust can guarantee that references haven't escaped the current thread, which means there is no stop the world pause anymore, only the current thread gets paused, which is acceptable.

Unless your memory allocator runs a form of garbage collection, which most of the advanced ones do! Worst memory performance issue I've ever seen was in a C++ program where the deallocation of a large object graph from one spot completely trashed the performance of the application across many threads...

Re: Rust Memory Management: Ownership vs. Reference Counting

#44
post #17

Earlier quoted context omitted.

The point of Rust, without counting `unsafe`, is to eliminate memory errors at compile-time. But the point of Rust, when including `unsafe`, is not to entirely eliminate memory errors at compile-time, but to make it feasible to cordon off the unsafe parts into realistically-auditable sections with documented safety invariants. At this it has been dramatically successful, almost beyond anyone's wildest hopes. I have w…

> without counting `unsafe`, Well, if you exclude all the bad code people have wrote, c is a safe language... See the point I'm making here? If coders couldn't be trusted multiple times in the past, and we had to invent language level features to correct them, but they still continued to make either the same, or a new, mistakes.... Why is rust any different? I guarantee you we will be complaining about unsafe rust in…

Even if you think having better developers would prevent the problem, the average Rust developer is probably better at writing bug free unsafe code than the average C developer.

Re: Rust Memory Management: Ownership vs. Reference Counting

#45

Earlier quoted context omitted.

> without counting `unsafe`, Well, if you exclude all the bad code people have wrote, c is a safe language... See the point I'm making here? If coders couldn't be trusted multiple times in the past, and we had to invent language level features to correct them, but they still continued to make either the same, or a new, mistakes.... Why is rust any different? I guarantee you we will be complaining about unsafe rust in…

The difference I see there is any line in a C codebase could have these issues, whereas in Rust they're specifically marked as unsafe sections, with the language having a clear list of invariants it expects the programmer to uphold in an unsafe block. Additionally Rust has a culture of developers specifically justifying the unsafe block and why it's correct in comments. It's a massive reduction of the scope of the co…

> The difference I see there is any line in a C codebase could have these issues

Not true.

> Additionally Rust has a culture of developers specifically justifying the unsafe block and why it's correct in comments

Yeah, if your on the message board. Wait til rust hits real world levels of usage and shit code begins to emerge....

It's easy to sit on that pedestal when your essentially a novelty language in comparison to amount of legacy code in production

Re: Rust Memory Management: Ownership vs. Reference Counting

#46

Solid intro. One pattern worth adding: when you're reaching for Rc > for graph-like or self-referential data, an index-based arena (Vec with usize "pointers") is often a third path that keeps you in plain-ownership land — at the cost of pointer identity and some bookkeeping. petgraph, slotmap, and most ECS libraries formalize this. Doesn't replace Arc for genuinely cross-thread shared lifetimes, but it eliminates a l…

I'm often curious how well the arena approach works for highly dynamic graphs. You end up having to reimplement the ref counting or a custom GC, which carries more risk.

Even memory locality of a arena doesn't provide benefit, because memory order does not mirror execution order.

Re: Rust Memory Management: Ownership vs. Reference Counting

#47

I've not really used Rust, and I can certainly appreciate the goal of the language. However this code bothers me, and I can't really articulate why. struct Node { value: i32, children: Vec >>>, parent: Option >>>, // Weak breaks parent→child cycle } I understand its all boxes inside boxes inside boxes, but as an outsider it looks confusing mixing data type semantics with memory managment semantics.

It bothers me too, maybe for different reasons, as an experienced rustacean. Code like this is a world of pain (in any language, might I add, even though Rust is the only one that shows you why with the syntax). Internally shared ownership is a huge anti-pattern and rarely achieves what you’re actually trying to do. Graphs like these are much better represented by splitting the topology from the node data, and using…

Do you have a simple example of how this is done correctly?

I always heard that but comming from Python internal references would be the way to go so it's not natural to me.

Re: Rust Memory Management: Ownership vs. Reference Counting

#49

Earlier quoted context omitted.

It bothers me too, maybe for different reasons, as an experienced rustacean. Code like this is a world of pain (in any language, might I add, even though Rust is the only one that shows you why with the syntax). Internally shared ownership is a huge anti-pattern and rarely achieves what you’re actually trying to do. Graphs like these are much better represented by splitting the topology from the node data, and using…

Do you have a simple example of how this is done correctly? I always heard that but comming from Python internal references would be the way to go so it's not natural to me.

Depending on the shape of the graph (arbitrarily connected, DAG, etc.), it just boils down to whatever convenient way you have of storing lists.

Node data in one list. Indices of node parents in another list of the same length. If you need to find children quickly, you can have another list of lists containing children indices.

The key is to consider the node’s position in the list as its ID, and refer to nodes by that index instead of the pointer.

In most cases, this model is both easier to work with and more performant. For example, you can usually get by with 32-bit indices instead of 64-bit pointers, so things are much more likely to be in cache.

Post reply on HN