7 ms·
There is no garbage collection in rust. There is no possible "five second gap". Wherever you would have written "socket.close()", in rust you can just say "dro
by ef4 12y ago
There is no garbage collection in rust. There is no possible "five second gap".
Wherever you would have written "socket.close()", in rust you can just say "drop(socket)". The difference is, it takes advantage of the ownership system to statically prove that you won't try to use the socket after close.
Or just let it go out scope and it will be dropped immediately. NOT eventually garbage collected.
- monocasa 12y ago> Wherever you would have written "socket.close()", in rust you can just say "drop(socket)". The difference is, it takes advantage of the ownership system to statically prove that you won't try to use the socket after close. Does a drop somehow say something to the type system as well, disallowing reads and writes afterwards? I'm new to rust, sorry if that's a stupid question.
- pcwalton 12y ago> Does a drop somehow say something to the type system as well, disallowing reads and writes afterwards? Yes.
- Leon 12y agoThe other poster says it proves operations won't happen again - does it do both?
- kibwen 12y agoYep! The owner of a thing can do the following: 1. Give ownership away to something else. 2. Free the object at the end of the scope. In order to do anything to the object, you give up ownership to the function that does it (which can then give it back, if it doesn't need ownership of the value any more and doesn't want to free it itself). This even applies to the `drop` function, which just takes ownership and then does nothing whatsoever to the passed-in value, allowing it to go out of scope immediately. So once you've called `drop(foo)`, you no longer own the value and so can't give it away to any reading or writing function, and you can't drop it for the very same reason.
- hrjet 12y agoCurious to know why `drop` isn't called automatically by the compiler as soon as possible (since the type system already seems to know it is safe). Is there a trade-off involved here?
- kibwen 12y agoFreeing resources as soon as humanly (computerly?) possible will optimize your memory usage, but can actually be worse for execution speed. If you're willing to use slightly more memory, it's generally faster to free memory in coarse chunks than one-thing-at-a-time. So even though Rust can conceivably free memory sooner, it might as well defer freeing until the end of the scope, since it can prove that that's safe. To take this to the logical extreme, see this awesome post from Walter Bright, where he doubles the speed of the D compiler by providing a custom malloc implementation that never frees, leaking all memory until the end of the process: http://www.drdobbs.com/cpp/increasing-compiler-speed-by-over-75/240158941 http://www.drdobbs.com/cpp/increasing-compiler-speed-by-over...
- hrjet 12y agoThanks. I can see the pro in that choice. But the con would be memory starvation (assuming that heap is bounded as in the JVM). I think one middle-path could be to mark the resource as released as soon as compiler detects it, and then release it 1. when the allocator is starved or 2. when the resource goes out of scope 3. when drop() is explicitly called
- kibwen 12y agoHeaps aren't bounded in systems contexts; a process is free to gobble up the entire address space if left unchecked, which would (hopefully) result in your process being killed by the OS. I believe we have discussed your first bullet point there, with regard to attempting to free waiting-for-the-scope-to-end-but-not-being-used memory in the event that allocation fails. But this is a hairy subject, and is beyond my expertise. Note that your third bullet point does cause memory to be freed immediately, because the `drop` function is a scope all its own.
- msopena 12y agoI'm curious about the drop implementation, which I found here (http://doc.rust-lang.org/src/core/home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libcore/mem.rs.html#348 http://doc.rust-lang.org/src/core/home/rustbuild/src/rust-bu...): pub fn drop<T>(_x: T) { } I understand that the drop function is simply taking ownership of the passed value so Rust knows that once "drop" finishes, the _x can be 'dropped'. But I though that the T had to be bound to have "Drop" trait (i.e. T: Drop) so that Rust knows it's possible to insert the call to 'drop' like _x.drop()?
- ef4 12y agoThat's a good question. If dropping was really implemented that way, every type would need to implement the Drop trait. Because otherwise there would be no way to free any memory at all. Instead, Rust knows how to free any object. Implementing Drop is optional, and you only need to do it if you want some custom behavior at destruction.
- kibwen 12y agoThe names are a bit confusing here, and I might petition to change them. The `drop` here is just a simple library function and isn't technically related to the `Drop` trait, which is implemented with magical compiler pixie dust and allows you to define a destructor via a `.drop` method. Anything that goes out of scope has this `.drop` method called automagically. You're correct in that if you were calling `x.drop()` explicitly, you would need to have a `Drop` bound on `T`.
- kibwen 12y agoIn fact, the `drop` function is totally trivial. It's just a function that takes ownership of a thing, then does nothing with it whatsoever. In other words, the function body is entirely empty! :) https://github.com/rust-lang/rust/blob/master/src/libcore/mem.rs#L348 https://github.com/rust-lang/rust/blob/master/src/libcore/me...
- portmanteaufu 12y agoHa! I've been using this function for ages and always assumed it was a compiler built-in. I love that it's just that simple.
- Double_Cast 12y agoThat's just too perfect. Of all things, your comment has raised my opinion of Rust the most.
- Leon 12y agoI have not used Rust before; does working with statistical analysis of runtime environments hinder debugging? In a multithreaded environment - does it pause the world for its runtime analysis or are there locks on shared resources representing ownership of individual objects, or does it do copies on writes of resources for idempotent operations as the references are moved around environment for lockless operations?
- steveklabnik 12y ago> does it pause the world for its runtime analysis The borrow checker is _entirely_ at compile time.
- ben0x539 12y agoTo be fair, resource disposal is sometimes "delegated" to runtime. But it's always a local concern, like a reference counter for a shared resource, or a mutable `Option<R>` value that can have the R resource taken out of it or put back into it dynamically. There's no creepy overarching runtime system that tracks individual objects from a distance.
- steveklabnik 12y agoYes, it's hard to figure out which way to talk about it. Rc<T> isn't really part of the borrow checker... it technically subverts it to do its own thing internally.
- ben0x539 12y agoI wouldn't really consider the whole ownership thing or specifically the mechanism that inserts destructor calls at the logical end of a value's lifetime part of the borrow checker either, but I dunno how the implementation is laid out.
- solipsism 12y agoJust to be clear (and to check this myself -- I'm just starting to learn Rust), a five second gap is actually possible right? Say I use a socket, stop using it, don't call drop(socket), and I don't leave the scope for 5 seconds because I'm busy doing something.
- ef4 12y agoYes, you are correct. What I was trying to explain is that the timing is deterministic and immediate. People are used to unpredictable GC and rightly don't want to trust it with thing like this.
- ben0x539 12y agoYeah, if you hold on to the thing in your scope, it won't go out of scope and won't be disposed of.