Et puis le ramasse-miettes est pas censé faire le ménage ?
Oui et non. La JVM « standard » (celle d’Oracle ou OpenJDK, c’est la même) fonctionne comme
ça : tu définis une quantité de mémoire allouée au démarrage, et une quantité de mémoire max. Quand tu as besoin de mémoire, la JVM regarde si tu as assez de RAM allouée :
- Si oui, ben il crée l’objet.
- Si non, une procédure se met en route.
La procédure exacte dépend de la version de la JVM et du garbage collector utilisé. Mais en gros, c’est un compromis entre « j’alloue plus de mémoire » (ce qui peut être long et peut échouer) et « je nettoie la mémoire » (ce qui peut être très, très long). Généralement tu as 2 types de garbage collection : un rapide qui permet de dégager facilement tous les objets qui sont d’évidence inutiles, et un qui va plus en profondeur, mais qui peut carrément mettre la JVM en pause le temps de faire son job. Le premier se contente normalement de rendre la mémoire disponible dans la JVM (la consommation mémoire du processus global ne bouge pas) ; le second peut désallouer de la mémoire, mais c’est rare, il faut qu’il y en ai beaucoup de libre.
C’est très simplifié et n’est vrai que dans les grandes lignes, mais l’idée est là.
La légende de Java = consommateur de mémoire vient généralement d’une mécompréhension du système de machine virtuelle avec de la mémoire allouée, et de ce que ça implique. L’idée derrière la JVM, c’est que tant qu’on a pas besoin de libérer de la mémoire, il n’y a aucune raison de le faire. Il « suffit » normalement de bien paramétrer la mémoire max allouable.