A lot of people use garbage collected languages because garbage collection isn't an issue in their projects... until it is. And then folks who really have to deal with it, get to learn about their garbage collector and how to manage memory allocation in their apps.
But to some how claim that the productivity savings that folks get from deferring learning about the details about their language's garbage collector is somehow problematic, because in a subset of cases, you do care about object allocation and garbage collection is a pretty silly argument (especially in the face of the article's admission that garbage collection has won out).
Garbage collection for most people is a tool of convenience. When the tool becomes inappropriate, yes, people do have to learn how to optimize their code. None of this should shock us, or keep us from using garbage collectors.
Well, the problem is that doing explicit memory management in a language that's built around GC is usually far less convenient than doing explicit memory management in a language that isn't (like C++). For example, in C++ you can use templates and placement new to write generic free lists that get specialized to the type of object in use at compile time, and they still allow you to use the regular old "new" syntax for calling the constructor. By contrast, you can write free lists in Java/C#/Python/Ruby/JS/etc, but you won't get that nice "new" syntax. (Not to mention that you don't get the same control over memory layout that you do in C++.)
Explicit memory management in GC'd languages is also less predictable: Java can allocate objects on the stack via escape analysis, but if the object is determined to escape then it gets silently demoted to the heap instead. In performance-critical code, this silent demotion can lead to a hard-to-find bug.
To me, the obvious solution is to build constructs into our GC'd language that nevertheless make explicit memory management predictable and convenient when the programmer wants to use it. A requirement for predictability is that whether an object is garbage collected needs to somehow be encoded into the type of that object (either via a static type or via a dynamic type). This is the philosophy we're following in Rust, and it's also the philosophy some of my colleagues are working on for JavaScript (via the Binary Data API).
What's nice about that syntax? In every language that I've used which has it (C++, Java, C#, JavaScript), it's been a royal pain in the butt. It makes it harder to swap in alternate factory behavior and requires remembering a few arbitrary extra rules, like operator precedence (no matter how many times I write `new Foo().bar()`, it still doesn't parse right in my head).
Ruby, SmallTalk, and Objective C get this right: Allocation is distinct from initialization (new vs init) and both use standard message passing / method call semantics.
We need semantic memory, but there is a limit to how far a language can take this. Ultimately you are sitting on top of void* malloc(size_t, size_t). A systemic rethink from HW on up is in the cards. Whether it will happen in 10 or 20 years, I am not sure, but it will happen.
Weak references are one such construct, and in AS3 are a real life-saver. Ironically, though, the popular problem is that things are collected too fast...when the real issue is that some things are never collected, and no one notices. I think GC languages would do well to provide an interface for monitoring not just memory usage, but performance impact of the GC process itself.
One problem here is that because of the complexity required to make a modern garbage collector manage memory effectively, when the GC fails to do its job properly it is far more complicated to fix ('optimise') than in a language with explicit allocation. The higher-level a language the less predictable its memory usage.
So in the scientific python community, we just push things down into C when there are performance problems, generally this is mostly done when CPU is the issue, but it seems that would also be valid approach if GC is becoming an issue.
But to some how claim that the productivity savings that folks get from deferring learning about the details about their language's garbage collector is somehow problematic, because in a subset of cases, you do care about object allocation and garbage collection is a pretty silly argument (especially in the face of the article's admission that garbage collection has won out).
Garbage collection for most people is a tool of convenience. When the tool becomes inappropriate, yes, people do have to learn how to optimize their code. None of this should shock us, or keep us from using garbage collectors.