Une première modification expérimentale a été ajoutée à OpenJDK 9 afin que la JVM puisse comprendre qu'elle s'exécute dans un conteneur et ajuster les limites de mémoire en conséquence. Malgré l'augmentation de popularité des conteneurs au cours de ces dernières années, de nombreux outils, y compris la JVM, utilisent toujours les paramètres de l'hôte pour évaluer les ressources disponibles, souvent suite à un court de mémoire avec des messages d'erreur déconcertants. Cette modification, qui pourrait être mise à la disposition du public une fois que Java 9 sera publié, est une tentative pour empêcher un grand nombre de ces scénarios.
Les technologies de conteneurs telles que Docker, Heroku or Kubernetes, entre autres, sont une forme de machines virtuelles légères basées sur le système d'exploitation Linux. Leurs empreintes réduites leur permettant d'offrir une fonctionnalité très similaire aux machines virtuelles plus rapidement et de consommer moins de ressources, mais elles présentent également des inconvénients : alors que les machines virtuelles complètes simulent toute une pile de matériel dédié, ce qui signifie que les logiciels existants fonctionnent comme prévu, les technologies utilisent le matériel et l'OS de l'hôte, ce qui signifie que le logiciel qui repose sur les informations de l'hôte risque de ne pas connaître les contraintes supplémentaires imposées par les conteneurs. Fabio Kung, développeur du service conteneurs Linux chez Netflix (également connu sous le nom de Titus), a écrit en 2014 un article intéressant expliquant ces effets ; bien que certains contenus de l'article pourraient être périmés à ce jour, il sert toujours comme une bonne introduction sur le sujet.
La JVM n'est pas étrangère à cela. Si la limite maximale de mémoire n'a pas été spécifiée avec -Xmx
, la JVM la définit comme une fraction de la mémoire physique (généralement un quatrième, mais peut varier) ; cela peut ne pas prendre en compte les limites imposées par le conteneur. Le changement proposé vise à prévenir ce problème en vérifiant si la JVM s'exécute dans un Control Group ou cgroup, comme la technologie Linux que la plupart des technologies de conteneurs utilisent pour imposer des limites sur l'utilisation du matériel et les autres ressources. Si la JVM détecte qu'elle s'exécute dans un cgroup, elle essaiera de trouver la limite de mémoire définie en elle et considérera une telle limite comme étant la mémoire physique disponible, et fixant par la suite tous les autres paramètres en fonction. Ceci est encore expérimental, et par conséquent ne sera appliqué que s'il est activé avec l'option -XX:+UseCGroupMemoryLimitForHeap
.
Incorporé au noyau Linux depuis 2008 et redessiné en 2013, cgroups isole l'utilisation des ressources et permet aux applications de contrôler l'accès à la mémoire, au CPU, aux E/S et aux réseaux, entre autres. Différentes applications peuvent créer leurs propres hiérarchies de Control Group avec des limites différentes par groupe, ce qui signifie qu'une application ne sait pas a priori le groupe dans lequel elle s'exécutera. C'est pourquoi la JVM ne peut que deviner les cgroups et la limite mémoire potentielle en place.