web-dev-qa-db-fra.com

Pourquoi la JVM est-elle lente à démarrer?

Qu'est-ce qui rend la JVM (en particulier, l'implémentation de Sun) lente à fonctionner par rapport à d'autres runtimes comme CPython? Mon impression était que cela a principalement à voir avec une cargaison de bibliothèques chargées, qu'elles soient nécessaires ou non, mais cela semble ne pas prendre 10 ans à résoudre.

À bien y penser, comment l'heure de démarrage de la JVM se compare-t-elle au CLR sous Windows? Et le CLR de Mono?

MISE À JOUR: Je suis particulièrement préoccupé par le cas d'utilisation de petits utilitaires enchaînés comme cela est courant sous Unix. Est-ce que Java convient maintenant à ce style? Quelle que soit la surcharge de démarrage Java encourue, cela s'ajoute-t-il pour chaque Java, ou les frais généraux ne se manifestent-ils vraiment que pour le premier processus?

52
Jegschemesch

Voici ce que Wikipedia a à dire sur la question (avec quelques références).

Il semble que la plupart du temps soit pris juste pour charger des données (classes) à partir du disque (c'est-à-dire que le temps de démarrage est lié aux E/S).

19
Naaff

Juste pour noter quelques solutions:

Il existe deux mécanismes qui permettent un démarrage plus rapide de la JVM. Le premier est le mécanisme de partage de données de classe, qui est pris en charge depuis Java 6 Update 21 (uniquement avec la machine virtuelle du client HotSpot, et uniquement avec le garbage collector série pour autant que je sache)

Pour l'activer, vous devez définir - Xshare (sur certaines implémentations: - Xshareclasses ) Options JVM.

Pour en savoir plus sur la fonctionnalité, vous pouvez visiter: Partage de données de classe

Le deuxième mécanisme est un Java Quick Starter. Il permet de précharger des classes au démarrage du système d'exploitation, voir: Java Quick Starter pour plus de détails.

8
Alexandr

L'exécution d'une application triviale Java avec la JVM client 1.6 (Java 6) semble instantanée sur ma machine. Sun a tenté de régler la JVM client pour un démarrage plus rapide (et la JVM client est la valeur par défaut), donc si vous n'avez pas besoin de beaucoup de fichiers jar supplémentaires, le démarrage devrait être rapide.

5
jdigital

Si vous utilisez HotSpot de Sun pour x86_64 (64 bits compilés), notez que l'implémentation actuelle ne fonctionne qu'en mode serveur, c'est-à-dire qu'elle précompile chaque classe qu'elle charge avec une optimisation complète, tandis que la version 32 bits prend également en charge le mode client, qui retarde généralement l'optimisation et optimise uniquement les pièces les plus gourmandes en CPU, mais a des temps de démarrage plus rapides.

Voir par exemple:

Cela étant dit, au moins sur ma machine (Linux x86_64 avec noyau 64 bits), la version HotSpot 32 bits prend en charge le mode client et serveur (via les indicateurs -client et -server), mais par défaut en mode serveur, tandis que la version 64 bits ne prend en charge que mode serveur.

4
Paggas

Cela dépend vraiment de ce que vous faites pendant le démarrage. Si vous exécutez l'application Hello World, cela prend 0,15 seconde sur ma machine.

Cependant, Java est mieux adapté pour fonctionner en tant que client ou serveur/service, ce qui signifie que le temps de démarrage n'est pas aussi important que le temps de connexion (environ 0,025 ms) ou le temps de réponse aller-retour temps (<< 0,001 ms).

3
Peter Lawrey

Il y a de nombreuses raisons:

  • beaucoup de jars à charger
  • vérification (s'assurer que le code ne fait pas de mal)
  • JIT (compilation juste à temps)

Je ne suis pas sûr du CLR, mais je pense qu'il est souvent plus rapide car il met en cache une version native des assemblys pour la prochaine fois (il n'a donc pas besoin de JIT). CPython démarre plus rapidement car il s'agit d'un interpréteur et l'IIRC ne fait pas de JIT.

1
Zifre

En plus des éléments déjà mentionnés (chargement de classes, en particulier à partir de fichiers JAR compressés); s'exécutant en mode interprété avant que HotSpot ne compile le bytecode couramment utilisé; et la surcharge de compilation HotSpot, il y a aussi pas mal d'initialisation unique effectuée par les classes JDK elles-mêmes. De nombreuses optimisations sont effectuées en faveur de systèmes plus longs où la vitesse de démarrage est moins préoccupante.

Et en ce qui concerne le pipelining de style Unix: vous ne voulez certainement PAS démarrer et redémarrer JVM plusieurs fois. Cela ne va pas être efficace. Le chaînage des outils devrait plutôt se produire dans la machine virtuelle Java. Cela ne peut pas être facilement mélangé avec des outils Unix non Java, sauf en démarrant ces outils à partir de JVM.

1
StaxMan

Toutes les machines virtuelles avec un système de type riche tel que Java ou CLR ne seront pas instables par rapport aux systèmes moins riches tels que ceux trouvés en C ou C++. Ceci est en grande partie dû au fait qu'il se passe beaucoup de choses dans le VM, beaucoup de classes sont initialisées et sont requises par un système en cours d'exécution. Les instantanés d'un système initialisé aident mais cela coûte toujours de charger cette image en mémoire, etc.

Une classe de paquebot simple de style bonjour avec un principal nécessite encore beaucoup à charger et à initialiser. La vérification de la classe nécessite beaucoup de vérification et de validation des dépendances, ce qui coûte du temps et de nombreuses instructions CPU à exécuter. D'un autre côté, un programme C ne fera rien de tout cela et contiendra quelques instructions, puis invoquera la fonction imprimante.

0
mP.