5 ms·
Not sure why you are being downvoted. I agree with you, the whole thing seems archaic. Downvoters care to comment on why this is relevant to a modern programmin
by general_failure 12y ago
Not sure why you are being downvoted. I agree with you, the whole thing seems archaic. Downvoters care to comment on why this is relevant to a modern programming language and try to convince us (and not the other way around)? Give me a good example of why I should care. Performance? Do you have numbers?
- pcwalton 12y agoIf you mean "do you have numbers as to why you might not want GC in all scenarios", yes. http://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf http://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf
- pkolaczk 12y agoGenerally I agree that you don't want GC in all scenarios, but the paper you cite has several flaws which makes its conclusions very far from truth. 1. It is based on non-production JVM and does not use the same algorithms that are used in production level VMs. There is a huge performance difference between any GC from 1990s and modern generational GC used in production-level VMs. 2. Some part of the experiment involved simulation. You must be very careful with extrapolating simulation results onto real world. Actually someone on the Internet rerun one of the same experiment using non-simulated VM and got totally different results, but now I can't find that blog post :( 3. It compares GC to "ideal" manual memory management, ignoring the fact that manual memory management is not free either. Things like heap fragmentation or computational cost of running allocation/deallocation code do exist and may cause also some real problems. The costs lie elsewhere, but that doesn't mean they don't exist. My experience with large applications is completely different than the conclusion of the paper. Unless you're doing something completely crazy like generating several GBs of garbage per second, modern generational GCs overhead is typically very small (<5%) with only 20-50% more memory than the live set size, not 3-5x as the paper claims. The biggest pain not solved completely are pauses, but researchers are actively working on it and things are getting much better.
- pcwalton 12y ago> 3. It compares GC to "ideal" manual memory management, ignoring the fact that manual memory management is not free either. Things like heap fragmentation or computational cost of running allocation/deallocation code do exist and may cause also some real problems. The costs lie elsewhere, but that doesn't mean they don't exist. No, it doesn't; it uses malloc and free, counting the costs of allocation and deallocation using a traditional memory allocator. (In fact, if anything, that's unfair to traditional memory allocators, as high-performance code will often use things like bump-allocating arenas which significantly outperform malloc and free. It also uses dlmalloc, which is outpaced by jemalloc/tcmalloc these days, although if the benchmarks are not multithreaded the difference will be small.) Heap fragmentation exists in GC systems as well, and fragmentation in modern allocators like jemalloc is very small.
- pkolaczk 12y agoOk, point taken, however their cost analysis is based on "simulated cycles", which is extremely simplified. With modern CPUs doing caching, prefetching, out-of-order execution I seriously doubt its accurate. malloc/free have typically a tendency to scatter objects around the whole heap, while compacting GCs allocate from a contiguous region - so a properly designed research experiment would take that into account. Hans Boehm did experiments on real programs and found that using compacting GCs actually speeded up some programs because of better cache friendliness. As for heap fragmentation - it does not exist in some GC systems, like G1 or C4. And fragmentation is also extremely workload dependent - it might be "very small" for most cases and for some might be as much as 5x (Firefox struggled a lot from this).
- jasode 12y ago> , modern generational GCs overhead is typically very small (<5%) with only 20-50% more memory than the live set size, not 3-5x as the paper claims. Another set of GC tests mentioned by the famous Drew Crawford article [1] said 4x to 6x was the sweet spot. A followup commenter wanted to clarify that the "best GC algorithms" worked within 2.5x. Whether its 2.5x or 4x, it's a counterpoint to the claims of only 50% more memory. Perhaps there are drastically different workloads skewing the tests. (I didn't thoroughly read both cited papers.) [1] http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/ http://sealedabstract.com/rants/why-mobile-web-apps-are-slow...
- Peaker 12y agoLots of GC vs Manual MM do a disservice to manual MM, by comparing GC to a strawman with lots of malloc/free. IME, manual MM often embeds allocations within each other and/or places allocation on the stack. Both of these options make manual MM far cheaper than GC, rather than slightly cheaper as shown in these papers.
- pkolaczk 12y agoThere is nothing that prevents a GCed language to allocate things on the stack. Also I'm afraid using std::string in C++ causes more allocs/frees than typical use of Strings in Java/C#, because the former can't be safely shared and must be copied - on the heap.
- Peaker 12y agoA GCed language requires good stack escape analysis. Unless you expose it to the programmer for at least semi-manual MM, it is bound to have false negatives, where you pay for the allocation on the heap unnecessarily. I totally agree about std::string. I think C++ with the conventional libraries is actually an example of how to do manual MM badly.
- ExpiredLink 12y agoThe GC argument is a straw man. You can have automatic resource management without GC (actually, GC-languages like Java and C# are at odds with automatic resource management) and without manual ownership semantics a la C++ and Rust.
- andreasvc 12y agoCan you give an example of automatic resource management without GC?
- Kutta 12y agoRust is pretty much the first mainstream-ish language ever to have substructural typing as a core feature. I can't see how this is archaic.
- pcwalton 12y agoTo be fair, C++ has an approximation of it with move semantics/rvalue references—and I'm really glad that it does, since it makes unique pointers much more mainstream of a concept than it would have been otherwise. (Rust tries to avoid unfamiliar concepts with no analogues in other languages.) It's just not safe in C++; there are lots of ways to get undefined behavior via use-after-move.
- DCKing 12y agoGarbage collection is not acceptable in some scenarios, because garbage collection implies unpredictable performance, slower performance, and comparatively heavy runtime dependencies. This is all fine for many applications, but not for stuff like operating systems, JITs, layout engines and other stuff generally called 'systems programming' where performance and lack of runtime dependencies is key. Those languages generally do not require garbage collection (although Rust does support it optionally) and therefore must provide memory management semantics. Rust is a language that caters to the oft-neglected field of systems programming. It does so by solving many problems of C++ which is mostly used in that area, and introducing/combining many features newish to systems programming languages and programming languages in general. ExpiredLink is being downvoted for missing that point.
- zackmorris 12y agoIf someone who knows a lot about garbage collection stumbles onto this, I've always wondered if stop-the-world garbage collection is only a necessity for multithreaded code. For example, imagine a single-threaded language like Go where the only way to communicate with any other threads/processes was through sockets, with no shared memory whatsoever. Would it still be necessary to stop the world? Or would it be possible to stop only the current thread periodically, and collect garbage with a known or fixed overhead? Bonus points: if so, then would it be possible to abstract shared memory with something like a software transactional memory (STM) that uses only sockets and copy-on-write somehow to completely avoid the stop-the-world issue? It just seems to me that if stop-the-world was tackled once and for all, so that we could always limit collection times, then so much of the complexity of low level programming would go away, and we wouldn't have to worry about reference counting, refcount loops, strong/weak references, etc etc etc..
- Jweb_Guru 12y agoWhile the data and anecdotal experience certainly support that manual memory management is faster, I think focusing on that specifically misses the point a bit, because you don't just get performance by taking out the garbage collector. For example, in systems programming memory is often not the only limited resource that needs to be cleaned up. In such situations, C++-style RAII is extremely valuable. While finalizers can be added to languages with garbage collectors, and indeed have been [1][2], it's not possible to predict when the resource destruction will occur, meaning that they end up requiring explicit (de)allocation of resources in pratice [3][4]. And if you still don't think it's a hard problem, take a look at some of the discussion the D community is currently engaged in over the same issue [5]. Another problem with GC that's already been brought up is the difficulty of using it in hard realtime systems. IBM has done a considerable amount of work in this area, including the development of a garbage collector designed specifically for realtime Java programming [6]. Some things to note about their solution include the heavy restrictions on the hard-realtime threads [7] (they are essentially disallowed from interacting with garbage collected objects, and in any case are not totally free of garbage collection), and that what are called realtime threads are still subject to nondeterministic pauses [8]. There are many more potential issues than this (e.g. signal handling [9]) but I hope you will agree that there is a clear need for languages without mandatory garbage collection. Given that such languages are necessary, it follows that it would be nice for there to be safe languages without mandatory garbage collection that can perform these tasks. While that doesn't necessarily mean you should care, it probably does, because even if you don't personally write programs with such requirements, you almost certainly use them. [1] C# Destructors, http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx [2] Java's Object#finalize, http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#finalize() http://docs.oracle.com/javase/8/docs/api/java/lang/Object.ht... [3] .NET's IDisposable (often used with using), http://msdn.microsoft.com/en-us/library/system.idisposable.aspx http://msdn.microsoft.com/en-us/library/system.idisposable.a... ; see also c# - Proper use of the IDisposable interface, http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface http://stackoverflow.com/questions/538060/proper-use-of-the-... [4] Java's AutoCloseable (designed for use with try-with-finally), http://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html http://docs.oracle.com/javase/8/docs/api/java/lang/AutoClose... [5] A few considerations on garbage collection, http://forum.dlang.org/thread/ljr549$1kti$1@digitalmars.com http://forum.dlang.org/thread/ljr549$1kti$1@digitalmars.com ; More radical ideas about GC and reference counting, http://forum.dlang.org/thread/ljrm0d$28vf$1@digitalmars.com http://forum.dlang.org/thread/ljrm0d$28vf$1@digitalmars.com ; GC vs Resource Management, http://forum.dlang.org/thread/hhpldnysndikzbkfbiqm@forum.dlang.org http://forum.dlang.org/thread/hhpldnysndikzbkfbiqm@forum.dla... [6] Introduction to the Metronome Garbage Collector, http://publib.boulder.ibm.com/infocenter/realtime/v1r0/index.jsp?topic=%2Fcom.ibm.rt.doc.10%2Frealtime%2Fmetro_introd.html http://publib.boulder.ibm.com/infocenter/realtime/v1r0/index... ; Real-time Java, part 4: Real-time garbage collection, http://www.ibm.com/developerworks/library/j-rtj4/ http://www.ibm.com/developerworks/library/j-rtj4/ [7] Using no-heap real-time threads, http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic/com.ibm.rt.doc.10/realtime/noheaprt.html http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic... ; in particular, Constraints on Java threads when running with NHRTs, http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic/com.ibm.rt.doc.10/realtime/nhrt_thread_constraints.html http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic.... [8] Metronome Garbage Collector limitations, http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic/com.ibm.rt.doc.10/realtime/metro_limit.html http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic... ; Metronome behavior in out of memory conditions, http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic/com.ibm.rt.doc.10/realtime/metro_trouble_oom.html http://publib.boulder.ibm.com/infocenter/realtime/v1r0/topic... [9] See, for example, Asynchronous Signals in Standard ML, http://www.smlnj.org/compiler-notes/90-tr-reppy.ps http://www.smlnj.org/compiler-notes/90-tr-reppy.ps ; section 5.2 gives a good overview of why truly preemptive signal handling, often a necessary part of systems programming, is not in general possible in a system with garbage collection.