Hmm nan, on a toujours pu plus ou moins pu forcer (bon, à une époque c'était simplement une incitation forte) le Garbage Collector à tourner avec un appel à GC.Collect() par exemple.
Le gros défaut de ce type de système, c'est que tu puisses pas avoir des *objets* à portée explicitement réduite (typiquement, les objets alloués sur la piles en C++ c'est pratique) et que tu sois systématiquement obligé d'allouer des objets à part entière. Mais ça, ça casserait complètement la sécurité mémoire, donc en contrepartie, en .NET, on a les types valeurs, qui sont formidables si bien utilisés, et parfois abominables si mal utilisés

L'avantage d'un langage basé sur le CLR ou la JVM par exemple (mais pas la JVM en vrai vu que cette chose ne libère jamais la mémoire

), c'est que le Garbage Collector peut compacter la mémoire. C'est typiquement un des problèmes que rencontre le gestionnaire mémoire de Firefox par exemple (si tu t'amuses à regarder), c'est qu'à certains moments, la mémoire est fragmentée au point que 25% de l'espace alloué soit inutilisé. Typiquement le genre de problèmes que tu auras beaucoup de mal à régler avec un langage natif qui te « laisse gérer » ta mémoire comme tu veux.
Après tout est question de compromis, mais il est certain qu'on a pas encore trouvé la meilleure solution au problème.