web-dev-qa-db-fra.com

Que se passe-t-il lorsque la JVM manque de mémoire pour allouer pendant la période d'exécution?

Après avoir pensé longtemps d'une manière générique de poser cette question (et de ne pas en trouver un), je vais juste le demander comme exemple concret:

Supposons que j'ai une machine Linux qui comporte 1 Go de mémoire qu'il peut attribuer aux processus (total des totaux d'échange d'échange de 1 Go).

J'ai une version 7 standard Oracle Hotspot JVM version 7 installée sur la machine. Si à un moment donné, il y a suffisamment de programmes de sorte que seulement 400 Mo de 1 Go sont gratuits et je commence un Java programme à ce moment-là avec les drapeaux JVM suivants:

Java -Xms256m -Xmx512m -jar myJar.jar

que s'est-il passé? :

A. Le JVM ne parvient-il pas à commencer tout de suite car il essaiera d'allouer toutes les 512 Mo de mémoire et d'échouer (en raison du fait qu'il n'y a pas assez de mémoire disponible pour le moment)?

si le JVM commence:

si, à un moment donné, le processus d'exécution Java aura besoin de plus de 400 Mo de mémoire (et il n'y a toujours que 400 Mo de mémoire qui est libre que ce que le courant Java = processus déjà utilisé), que se passera-t-il:

B. Est-ce que le Java est-il échoué avec un OutofMemRoyError?

C. Est-ce que cela échouera avec une autre erreur (standard)?

D. Est-ce un comportement indéfini?

20
Shivan Dragon

-Xmx définit simplement la taille maximale du tas. Il ne fait aucune garantie sur Wether il y a tellement de mémoire ou non. Il ne garantit que le tas ne sera jamais plus grand que la valeur donnée. Cela dit, l'option B.) se produira, un exceptionnel sera lancé.

9
Polygnome

Supposons que j'ai une machine Linux qui comporte 1 Go de mémoire qu'il peut attribuer aux processus (total des totaux d'échange d'échange de 1 Go).

Ma première réponse serait, à moins que vous ne parliez d'un téléphone, j'aurais plus de mémoire. Vous pouvez acheter 16 Go (B = Bit, B = octet) pour moins de 100 $.

le JVM échoue-t-il tout de suite car il essaiera d'allouer tous les 512 Mo de mémoire et d'échouer (en raison du fait qu'il n'y a pas assez de mémoire disponible pour le moment)?

Cela peut arriver si votre système n'a pas de 512 Mo (plus une augmentation de la tête), car il attribue la mémoire virtuelle continue utilisée pour le tas au démarrage.

Même si vous avez 550 MB GRATUIT, le programme pourrait ne pas commencer comme il est nécessaire de charger plus que le tas.

est-ce que le Java processus échoue-t-il avec un ex-de -MemororyError?

Cela peut arriver si votre programme utilise 512 Mo lors de l'exécution, quelle que soit la quantité de mémoire que votre machine a. Cette erreur ne se produira qu'une fois que votre JVM a commencé. Vous n'obtiendrez pas cette erreur s'il ne peut pas démarrer.

est-ce que cela échoue avec une autre erreur (standard)?

Cela est possible si vous manquez d'espace de swap après le démarrage du programme. Il est rare et n'arrive que sur une machine sévèrement surchargée. Ce que j'ai vu, c'est que les accidents JVM sont dus à une défaillance d'un système d'exploitation à faible niveau d'allocation de la mémoire.

Java 6 Mise à jour 25 VM Crash: mémoire insuffisante

7
Peter Lawrey

Si vous avez tellement de mémoire occupée que l'espace libre ne peut même pas maintenir une JVM inactif, vous obtiendrez soit une erreur d'erreur indiquant que le programme n'a pas suffisamment de mémoire, ni que la JVM se bloque.

Si vous pouvez exécuter la JVM, vous pouvez spécifier la limite sur l'espace de tas avec -xmx. Cela ne signifie pas que tout le tas sera alloué par JVM au début - ce n'est qu'une limite interne. Si le JVM voudra augmenter l'espace du tas, mais il n'ya pas assez de mémoire, ou si vous avez besoin de plus de tas que spécifié par -xmx, vous obtiendrez OutFMororyError dans actuellement en cours d'exécution Java Programmes.

Dans une condition très extrême, vous pouvez manquer de mémoire libre pendant que le JVM est en marche et que la JVM nécessite en même temps plus de mémoire pour son fonctionnement interne (pas l'espace de démarrage) - alors le JVM vous dit qu'il avait besoin de plus de mémoire, mais ne pouvait en obtenir aucun, et se termine, ou il va s'écraser de manière directe.

2
Jakub Zaverka

OutOfMemroyError sera "jeté lorsque le Java machine virtuelle ne peut pas affecter un objet car il est hors de mémoire et plus de mémoire ne pouvait plus être mise à disposition par le collecteur des ordures. "

Donc, en essence, "b. Le Java échec de l'échec avec un OutOfMemroyError" .

2
XenoRo

Le processus JVM fonctionnera dans la mémoire virtuelle, la question de l'allocation d'autres processus fonctionnant est pertinente, mais pas complètement déterminante.

Lorsque la JVM ne peut pas allouer plus de mémoire (pour une raison quelconque), le processus lui-même ne se termine pas, mais commence plutôt à lancer OutOfMemoryError -dans le JVM, mais pas externe au JVM. En d'autres termes, la JVM continue de fonctionner, mais les programmes exécutés au sein de la JVM échoueront généralement, car la plupart ne gèrent pas de manière adéquate de la mémoire faible. Dans cette affaire assez courante, lorsque le programme ne fait rien pour gérer l'erreur, la JVM mettra fin au programme et quittera. En fin de compte, cela provient de l'allocation de la mémoire, mais pas directement. Il est possible qu'un morceau de code s'ajoute à une condition de mémoire faible et continuez à courir.

Et d'autres ont souligné, il arrive parfois que la JVM elle-même ne traite pas bien la mémoire basse, mais c'est une condition assez extrême.

1
eh9