Stéphane Fosse

RAM bon marché, garbage collector
Ce qui a vraiment fait exploser la consommation mémoire des logiciels depuis 1995

Publié le

J'ai une conviction ancienne, forgée par la pratique plus que par la lecture : la bascule vers Java au milieu des années 1990 a fait exploser la consommation mémoire des logiciels. Avant, en C ou C++, chaque développeur gérait sa mémoire à la main : allocation et libération, la discipline était obligatoire pour les coûts et la sécurité. Après, le garbage collector s'en est chargé, et personne n'a plus vraiment eu à s'en soucier. J'ai voulu vérifier si cette intuition tenait face aux chiffres. Elle tient, mais elle est plus riche que je ne le pensais.

Premier point troublant : le calendrier. Niklaus Wirth publie en 1995 son essai A Plea for Lean Software, où il formule la loi qui portera son nom : le logiciel ralentit plus vite que le matériel n'accélère. La même année, Java sort au grand jour. Ce n'est probablement pas une coïncidence de calendrier, mais la trace visible d'un même basculement d'époque : celui où la mémoire cesse d'être la ressource rare qui disciplinait le développeur.

Deuxième point : le prix de la RAM. Les séries historiques montrent qu'un mégaoctet coûtait encore autour de 32 dollars en 1994, avant de s'effondrer vers des fractions de centime par mégaoctet aujourd'hui. Quand une ressource cesse d'être rare, le calcul économique du développeur change mécaniquement : optimiser la mémoire devient moins rentable que d'optimiser le temps de développement. Le garbage collector n'a pas causé ce relâchement à lui seul, il l'a rendu confortable au moment précis où il devenait économiquement indolore.

Troisième point, et celui-là m'a surpris par sa précision : le surcoût du GC n'est pas qu'une impression, il est mesuré. Une étude comparant C++ et Java sur une charge identique montre que même avec une mémoire abondante, Java affiche un débit inférieur de 37 % à celui de C++ pour une même latence cible, l'écart s'expliquant par le travail continu du collecteur qui consomme du CPU même hors des pauses longues. Sur la mémoire elle-même, l'étude de référence de Pereira et al., qui compare 27 langages sur les mêmes problèmes, aboutit à un classement net : C consomme en moyenne 626 Mo, Rust 1087 Mo, C++ 2274 Mo, les langages à gestion manuelle restant nettement en dessous des langages à collecteur automatique sur la plupart des bancs d'essai. Et le lien avec le Green IT est direct : les mêmes travaux établissent une corrélation forte entre la mémoire totale utilisée sur la durée de vie d'un programme et l'énergie consommée par la DRAM.

Quatrième point, celui qui m'a fait nuancer ma propre position : le facteur graphique pèse au moins autant que le langage. La progression des besoins mémoire de Windows suit une courbe qui accompagne l'enrichissement du rendu bien plus que la seule évolution de l'OS. Windows 95 demandait 4 Mo, recommandait 8. Windows 98 réclamait 16 Mo. Windows XP montait à 64 Mo minimum, 128 recommandés. Contre quelques centaines de kilo-octets pour un OS en mode texte de la génération AS/400 ou mainframe. Le passage massif au graphique (fenêtres, polices, antialiasing) a un coût mémoire propre, largement indépendant du langage utilisé pour écrire l'application.

Reste une réserve méthodologique que je garde en tête avant de brandir ces chiffres comme une preuve définitive : une étude récente critique assez sévèrement les travaux de Pereira et al., en soulignant qu'ils sont souvent interprétés comme établissant un lien entre langage et consommation, alors qu'il s'agit d'associations statistiques dépendant fortement de l'implémentation retenue pour chaque banc d'essai. Un code Java bien écrit avec un GC bien réglé peut rester frugal. Un C++ mal architecturé, truffé de fuites, peut être pire. Le langage influence la distribution des résultats, il ne la détermine pas seul.

Ce qui m'intéresse au fond, ce n'est pas de qualifier un langage de coupable. C'est que la cause est bien multifactorielle et qu'elle dessine un phénomène plus large qui continue aujourd'hui sous d'autres formes : l'empilement des couches d'abstraction comme la virtualisation, les conteneurs, les frameworks JavaScript volumineux, chacune ajoutant son overhead au-dessus de la précédente au lieu de la remplacer, et les applications Electron, qui embarquent chacune un moteur Chromium complet pour afficher une messagerie. Le fil qui relie 1995 à aujourd'hui n'est pas Java. C'est un système économique complet où la RAM ne coûte (presque) plus rien, où le temps ingénieur coûte cher, et où le confort de développement prime systématiquement sur la sobriété de la machine cible. Même si l'impact de l'IA sur l'augmentation de la RAM ces derniers mois pourrait changer à nouveau la donne.

Le logiciel s'étend pour occuper toute la mémoire disponible, quelle que soit sa quantité.

— Niklaus Wirth, A Plea for Lean Software, 1995