4 ms·
Even in languages with a garbage collector you make decisions that impact the lifetime of an object. That is not what makes the memory management manual. For i
by brokencode 4y ago
Even in languages with a garbage collector you make decisions that impact the lifetime of an object. That is not what makes the memory management manual.
For instance, you can still have a memory leak in Java if you maintain a reference to an object that you never intend to use again. It’s still up to the programmer to prevent this.
> With true automatic memory management like tracing GC or reference counting, you have no idea where the or when the memory will be freed as you write the code, and the answer will usually be different over different invocations of the same code.
This just isn’t true, and it would be anarchy. You know that the object will be freed sometime after the last reference to it dies. This is the whole reason to use automatic memory management.
Reference counting approaches typically go even further and free the memory immediately when the last reference is eliminated.
And this is basically what Rust does with ownership. When the object goes out of scope and ownership is not transferred, the memory is freed. It’s just that it doesn’t always need the reference counting part. But you can rest assured that it will be freed.
With manual memory management, the programmer must manually free the object, and there is no automatic method to do this once there are no references. That is what makes it manual. The programmer might forget to free the memory or they might free memory too soon and try to use an object after it’s already been freed. This is not the case in Rust.
- Calavar 4y ago> And this is basically what Rust does with ownership. When the object goes out of scope and ownership is not transferred, the memory is freed. It’s just that it doesn’t always need the reference counting part. But you can rest assured that it will be freed. That's manual memory management. Like I said, the fact that you didn't explicitly write the call to free doesn’t make it automatic - that's just syntax sugar. Explicitly transferring ownership involves the programmer manually telling the compiler "keep this alive." If you're the one doing the bookkeeping, that's manual. Rust helps you with the bookkeeping, but it doesn't eliminate altogether. As opposed to a tracing GC, where you don't need decide on the scope of the value itself (just the scope of the reference), leave lifetime annotations, use std::move or the like to transfer explixitly ownership, or write out destructor/drop procedures to tell the compiler exactly how to free memory. The runtime does all the bookkeeping on its own. > The programmer might forget to free the memory or free memory too soon and use an object after it’s already been freed. This is not the case in Rust. Yes, it's possible to run into pathologic cases in any algorithm for automatic memory management where memory isn't freed - that's the nature of Turing completeness. No scheme for automatic memory management claims to be 100% foolproof. That doesn’t mean that tracing GC is actually manual memory management. > This just isn’t true, and it would be anarchy. You know that the object will be freed sometime after the last reference to it dies. This is the whole reason to use automatic memory management. That's a surprisingly literal interpretation of what I said. What I mean by "you have no idea" is that if you read a function that uses reference counting or tracing GC, you cannot say for sure if there are going to be deallocation when that function is called, even for a pure function where you know the particular input values to that function. That's because the decision to deallocate depends on the whole program state, including references to the same value that may be held by some third party library that you linked in. As opposed to Rust, where (unless you are using Rc or Arc) you could annotate that function with comments about where things will be deallocated and if you understand the semantics of the language you will be right every time. Not because you are a genius who can divine the machinatioms of the compiler/optimizer running through algorithms to automatically insert frees, but because you actually made those decisions yourself, whether implicitly or explicitly, by leveraging the semantics of the language. Like I said, this is not a new concept. You could write C++ code without any instance of new, delete, malloc, or free all the way back in the 80s.
- brokencode 4y agoThis argument is pointless because we have different definitions of automatic. Can we at least agree that Rust’s model prevents the following errors that manual memory management is prone to? - Using an object that has already been freed. - Failing to free an object that can no longer be accessed. To me, preventing those problems is the main benefit of automatic memory management. C++ will happily let you make either one of these mistakes, and that’s how Rust is different. I agree that Rust imposes a cost in the code to accomplish this compared to garbage collection. It’s up to the individual programmer to decide whether they think it is worth the benefits.