Emery Berger, a UMass Amherst computer science professor, hosts research papers on memory management, performance measurement, and heap security.
HN links his garbage collection versus malloc paper in debates about GC memory overhead, where commenters cite it as actual research on the question.
2005: "Quantifying the Performanceof Garbage Collection vs. Explicit Memory Management" (https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf)
[Edit] Also, 1993: "The Measured Cost of Conservative Garbage Collection" (http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.1816) [Anyone seen any work on conservative GC for existing languages since Boehm?]
Throughput-style garbage collection has mostly been solved; I believe the only outstanding problem is to reduce the necessary memory footprint towards the minimum required by the application. (On the other hand, the best memory management scheme is still an old-style Unix proggy that does bump-allocations in an arena and never frees memory until it terminates. Just don't let it run too long.)
Most of the work in GC has been towards reducing latency, which typically means different GC algorithms for different tasks. The ideal of a fast, real-time GC is still an open research project.
Explicit heaps are still not a solved problem, either, and they've been around longer than GC work (ahem*). With no static checking for leaks, use-after-free, and other issues, C memory management can be a nightmare unless you have iron-willed development discipline. The only real tools for dealing with those issues are run-time testing tools like valgrind, which among other things are horribly slow if you want to run them against a real workload.
Rust is an interesting case: it does an amazing job, if you use it for C++-like RAII…
> Because about 99% of the time the garbage collect is a negligible portion of your runtime
lol .. reality disagrees with you.
https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf#:~:text=We%20show%20that%20GenMS%2C%20an%20Appel%2Dstyle%20generational,sizes%2C%20ultimately%20running%2070%25%20slower%20on%20average.
On page 3 they broadly conclude that if you use FIVE TIMES as much memory as your program would if managed manually, you get a 9% performance hit. If you only use DOUBLE, you get as much as a 70% hit.
Further on, there are comprehensive details on the tradeoffs between style of GC vs memory consumption vs performance.
---
Moving a value from DRAM into a CPU register is an expensive operation, both in terms of latency, and power consumption. Much of the code out in the "real world" is now written in garbage collected languages. Our datacenters are extremely power hungry (as much as 2% of total power in the US is consumed by datacenters), and becoming more so every day. The conclusion here is that garbage collection is fucking expensive, in real-world terms, and we need to stop perpetuating the idea that it's not.
When talking about Garbage Collection they claim that "Even languages with highly optimized garbage collectors can’t match the performance of non-GC’d languages" and link to this paper: http://greenlab.di.uminho.pt/wp-content/uploads/2017/09/paperSLE.pdf However I cannot see where this paper supports the assertion (although Rust comes out well).
The particular problem is that malloc/free is not free of charge. Different allocators have complex internal implementations, plus you lose easy sharing of complex structures and compaction. So if you're using a GC you probably program in a different way, eg using more shared immutable structures, exploiting the advantages of GC.
Edit: A bit later they brush off this old favourite for GC-haters: https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf claiming that GC requires 5x as much memory. The problem with this paper is it assumes that malloc/free is cost-free and instantaneous, and that your programmer always calls free at the exact moment that the memory is no longer needed, both of which are extremely unrealistic.
I think using a different language, so a different compiler with a different level of maturity introduces too many conflating variables to decisively answer this question.
I don’t know the answer, either, but believe (corrections welcome) https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf hasn’t been refuted. It says GC needs 5 times the memory as manual memory management for equivalent performance, 3 times the memory for about equivalent performance.
Of course, that paper isn’t about reference counting. I think reference counting should see the same alloc/free patterns as manual memory management, but with larger allocation sizes, to accommodate for a reference count in every object allocated. Even if that, on average, doubles the allocation size, that 5 and 3 still would be 2½, respectively 1½.
That logic may be broken, but I also notice that iPhones typically have less memory than Android phones, yet seem to do well in reviews. That, too conflates variables, so GCvs Reference Counting may not be a big factor, but if not, what is the reason?
I think the real problem is the move from manual memory management to garbage collection. Garbage collection has immense advantages, and is indisputably the right choice for most application programming, but it only goes fast if you feed it lots of memory.
See figure 3 of this wonderful but terrifying paper:
http://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf
(Caveat: that was published in 2005, and garbage collection has improved since then. However, i doubt it has improved enough to invalidate its conclusions.)
The best collector there needed ~3x as much memory as a (admittedly superhumanly perfect) manually memory management to get to a competitive speed.
There are plenty of problems where that memory is available. But there are plenty where it is not. I can justify giving loads of memory to the application that makes my company money. I can't justify giving it to some tiny little log shipper or message forwarder or other random system utility that i want to run on every machine in my infrastructure.
So we are agreed that mixing tracing GCs with any other form of memory management (including another GC) is an unsolved problem. Good.
Swift is a disaster, also agreed. So?
For the rest: actual research disagrees with your forceful but unsubstantiated assertion:
https://2013.splashcon.org/details/oopsla-2013-papers/21/Taking-Off-the-Gloves-with-Reference-Counting-Immix
And once again, tracing GCs do well in microbenchmarks where you only check the cost of local operations. They are horrible when you take the global effects into account, with those local/benchmarking advantages not translating into real world use.
https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf
Very similar to JITs, which also do massively better in microbenchmarks than in production code:
http://blog.metaobject.com/2015/10/jitterdammerung.html
Oh, and integrating well and without high cost to fast languages where you have even more control is actually an important feature.