4 ms·
Props to Rust for tackling this head on, more languages should provide resource allocation that's deterministic, predictable and syntactically convenient. CPyt
by phunge 12y ago
Props to Rust for tackling this head on, more languages should provide resource allocation that's deterministic, predictable and syntactically convenient.
CPython's behavior is nice, but it seems to me it came about by accident. Big heavy resources use refcounting because everything uses refcounting. Plus, if CPython had true concurrency, across-the-board refcounting probably wouldn't have lasted nearly as long (reason being: multithreaded refcounting requires atomic ops which make them much more expensive).
But in the general language design world, IMHO, refcounting is actually a pretty good compromise for resource management. Because:
1) The efficiency lost compared to Rust's approach is probably immaterial (since the Big Expensive Object that you're mananaging dwarfs the refcounting -- syscalls and file descriptors are expensive). So I don't think zero overhead is critical.
2) Cycles are pretty easy to avoid when you're only refcounting Big Expensive Objects (FDs, mmapped buffers, etc. etc.) For a general runtime, refcounting is tricky. But if it's a special part of the language that's small, simple, and only for resource management, it's pretty convenient. I think it's worlds better than the approach of mixing GC and resource management -- language designers should admit that's a terrible idea.
- kibwen 12y agoI agree that refcounting is a great and usable compromise in this space, but your own comment flirts with why I don't think modern languages are chomping at the bit to base resource management on it: concurrency. Granted, I have no idea how much overhead is imposed by atomic operations vs. a stop-the-world or concurrent GC (if anyone has some data, I'd love to see it!). But given how it's become de rigeur for new languages to come with a baked-in concurrency story and emphasize concurrent applications, I don't blame them for not wanting to tie themselves to the RC cart.
- chetanahuja 12y ago"Granted, I have no idea how much overhead is imposed by atomic operations vs. a stop-the-world or concurrent GC." An atomic read/write/increment/decrement is a non-blocking (from the point of the view of a user code running on the CPU) CPU operation. The CAS operations required to do atomic inc/dec are relatively expensive compared to normal memory read/writes of course but nowhere near the scale of stop-the-world GC (where all threads in the runtime have to be blocked for a potentially large amount of time, sometimes measured in whole seconds or even 10's of seconds for large heaps). Anyone who has had to troubleshoot JVM's handling large heaps (in the ~10GB range) quickly learns to love deterministic costs of refcounted resource management.
- pjmlp 12y agoThat is an implementation issue. There are plenty of JVMs to choose from, even pauseless ones.
- chetanahuja 12y agoHah.. Implementation issue. That's a good one. It's just like an SUV not being landmine proof is an implementation issue. Just because somewhere a landmine proof humvee exists doesnt mean its attainable or practical for an ordinary user.
- Roboprog 12y agoRe: threads uber ref-counting. Hit one of my hot-buttons: Threads have got to be one of the most massive WOMBAT boondoggles of the last few decades. Pro) none of this slow inter-process-communication stuff! Con) EVERYTHING is now dangerous. (not quite, but close) But the industry (?) decided "TOTALLY worth it!" I forgot to mention that threads start a little faster than processes (well, quite a bit faster on a particular shitty OS in widespread use), but not so much faster that you won't need to pool and re-use the threads anyway. I think this is one area where Erlang (actor pattern), for instance, gets it right: pretend tasks run in their own process, and use an IPC proxy to send messages between the tasks/sub-programs, even if implemented with threads instead of OS level processes.