Sous Windows, le manque de mémoire était la principale source de plantages de Firefox — pourtant, de nombreux utilisateurs concernés disposaient de plusieurs gigaoctets de RAM physique libre. Windows plafonne la quantité de mémoire qu'une application peut valider à la taille de la RAM plus celle du fichier d'échange, et Firefox ne pouvait pas contrôler tout ce qui consommait cet « espace de validation » : les pilotes graphiques valident de la mémoire pour des textures rarement utilisées, mais qui compte tout de même dans la limite. Firefox avait passé des années à réduire sa propre consommation de mémoire et à surveiller les régressions, et aucun de ces efforts n'avait fait bouger le taux de plantages comme l'a fait l'astuce finalement retenue.
La réponse conventionnelle à une allocation impossible à satisfaire est d'abandonner : la plupart des chemins d'échec n'offrent aucun moyen raisonnable de continuer, si bien que le navigateur plantait de manière contrôlée. Cela revenait à considérer le plafond de l'espace de validation comme fixe, alors que sous Windows il ne l'est pas — le système d'exploitation agrandit automatiquement le fichier d'échange lorsqu'il est presque plein, augmentant la quantité de mémoire que les applications peuvent valider.
L'approche de Mozilla a consisté à faire attendre brièvement le processus principal lorsqu'une allocation échouait, puis à la retenter, laissant à Windows le temps d'agrandir le fichier de pagination. Cette pause apporte aussi autre chose : Firefox fonctionne en plusieurs processus et peut survivre à la perte de n'importe lequel d'entre eux sauf le principal ; ainsi, pendant le délai, un processus de contenu ou de GPU dont la mémoire s'emballe a tendance à mourir en premier, libérant de la place pour que le navigateur reprenne. Perdre une page web ou voir un bref clignotement vaut mieux qu'un plantage complet du navigateur.
L'astuce a été livrée dans Firefox 105 et a réduit de plus de 70 % les plantages du navigateur par manque de mémoire par heure d'utilisation active — bien au-delà des prévisions les plus optimistes de Mozilla. L'équipe avait déjà utilisé la même approche avec succès sur Firefox pour Android et Firefox OS, et une légère hausse des plantages d'onglets sous pression mémoire était la prochaine chose qu'elle s'était fixé de réduire.
Une allocation échouée n'est pas nécessairement fatale sous Windows — le système d'exploitation agrandit le fichier de pagination à la demande, si bien qu'attendre et retenter transforme un plantage par manque de mémoire en une brève pause.
Windows ne tue pas une application dont l'allocation échoue — l'appel renvoie une erreur, si bien que le processus peut choisir d'attendre et de réessayer au lieu de mourir.
Le plafond de l'espace de validation est extensible : Windows agrandit automatiquement le fichier d'échange lorsqu'il est presque plein, et une courte pause lui laisse le temps de le faire.
La conception multiprocessus de Firefox signifie que bloquer le processus principal laisse un processus de contenu ou de GPU rechargeable mourir en premier et libérer de la mémoire, protégeant ainsi tout le navigateur.
Le changement a modifié la gestion des échecs plutôt que l'utilisation de la mémoire, ce qui explique pourquoi une petite correction a surpassé des années de réduction de l'empreinte mémoire.
Lorsqu'une plateforme peut étendre une ressource à la demande, il faut marquer une pause au lieu de planter en cas d'échec — et, dans une application multiprocessus, laisser un sous-processus rechargeable absorber les dégâts en premier.
Suites
Firefox 105 a livré le comportement d'attente et de nouvelle tentative en septembre 2022, et la télémétrie a montré que les plantages du navigateur par manque de mémoire par heure d'utilisation active avaient chuté de plus de 70 % — « bien plus que nos prévisions les plus optimistes ». La pause a provoqué une hausse plus modeste des plantages d'onglets, que l'équipe s'est ensuite employée à réduire, et Mozilla a commencé à distinguer un faible espace de validation d'une faible mémoire physique afin que Firefox puisse réagir différemment et réduire l'échange. L'ingénieur Raymond Kraesig a mis en œuvre l'astuce et surveillé son impact ; la même technique avait déjà fonctionné sur Firefox pour Android et Firefox OS.
VÉRIFIEZ LES SOURCES
Les sources
- Improving Firefox stability with this one weird trick Mozilla Hacks · hacks.mozilla.org ·
- Hacker News discussion: Improving Firefox stability with this one weird trick Hacker News · news.ycombinator.com ·