49 votes

Où le code compilé JIT de .NET est-il mis en cache ?

Un programme .NET est d'abord compilé en code MSIL. Lorsqu'il est exécuté, le compilateur JIT le compile en code machine natif.

Je me demande :

Où est stocké le code machine compilé par JIT ? Est-il seulement stocké dans l'espace d'adressage du processus ? Mais comme le deuxième démarrage du programme est beaucoup plus rapide que la première fois, je pense que ce code natif doit avoir été stocké sur le disque quelque part, même après la fin de l'exécution. Mais où ?

Gracias.

77voto

Hans Passant Points 475940

La mémoire. Il s'agit de peut être mis en cache, c'est le travail de ngen.exe. Il génère une version .ni.dll de l'assemblage, contenant du code machine et stockée dans le GAC. Qui est automatiquement chargé par la suite, en contournant l'étape JIT.

Mais cela n'a pas grand-chose à voir avec le fait que votre programme démarre plus vite la deuxième fois. La première fois, vous avez ce qu'on appelle un "démarrage à froid". Qui est complètement dominé par le temps passé à trouver les DLL sur le disque dur. La deuxième fois, vous avez un démarrage à chaud, les DLL sont déjà disponibles dans le cache du système de fichiers.

Les disques sont lents. Un SSD est une solution évidente.

Pour info : ce n'est pas un problème exclusif au code géré. Les gros programmes non gérés avec beaucoup de DLLs l'ont aussi. Deux exemples canoniques, présents sur la plupart des machines de développement sont Microsoft Office et Acrobat Reader. Ils trichent. Lorsqu'ils sont installés, ils placent un "optimiseur" dans la clé de registre Exécuter ou dans le dossier Démarrage. Tout ce que font ces optimiseurs, c'est charger toutes les DLL que le programme principal utilise, puis quitter. Cela amorce le cache du système de fichiers, lorsque l'utilisateur utilise ensuite le programme, il démarrera rapidement puisque son démarrage à chaud est rapide.

Personnellement, je trouve cela extraordinairement ennuyeux. Parce que ce qu'ils vraiment est de ralentir tout autre programme que je pourrais vouloir lancer après m'être connecté. Ce qui est rarement le cas d'Office ou d'Acrobat. Je mets un point d'honneur à supprimer ces optimiseurs, à plusieurs reprises si nécessaire lorsqu'une fichue mise à jour les remet en place.

Vous pouvez aussi utiliser cette astuce, mais faites-le de manière responsable, s'il vous plaît.

11voto

Tim Lloyd Points 23571

Comme d'autres l'ont souligné, dans votre cas, le code est JIT sur une base par processus et n'est pas mis en cache. L'accélération que vous constatez lors de la deuxième charge est due à la mise en cache sur disque OS (c'est-à-dire en mémoire) des assemblages.

Cependant, alors qu'il n'y a pas de mise en cache (à l'exception de la mise en cache du disque du système d'exploitation) dans le bureau \server version du framework, il y a une mise en cache du code machine JIT dans une autre version du framework.

Ce qui est intéressant, c'est ce qui se passe dans le .Net Compact Framework (NETCF pour la version 7 de Windows Phone). Des progrès récents permettent de partager certains codes JIT entre des processus où le code JIT est effectivement mis en cache. Cela a été réalisé principalement pour améliorer les performances (temps de chargement et utilisation de la mémoire) dans les appareils limités tels que les téléphones mobiles.

Donc, pour répondre à la question, il n'y a pas de mise en cache directe du code JIT dans le bureau. \server mais il y en aura dans la dernière version du cadre compact, à savoir NETCF.

Référence : Nous croyons au partage

http://blogs.msdn.com/b/abhinaba/archive/2010/04/28/we-believe-in-sharing.aspx

7voto

Sam Points 595

Le code machine compilé par JIT est mis en mémoire cache par méthode, chaque fois qu'une méthode est exécutée pour la première fois. Je ne pense pas qu'il soit jamais mis en cache sur le disque.

Vous pouvez constater que le processus est plus rapide à charger la deuxième fois parce que Windows a mis en cache (en mémoire) les fichiers utilisés par votre processus (dlls, ressources, etc.) lors de la première exécution. Lors de la deuxième exécution, il n'est pas nécessaire d'aller sur le disque, alors que cela a pu être fait lors de la première exécution.

Vous pouvez le confirmer en Exécution de NGen.exe de précompiler le code machine pour votre architecture, et de comparer les performances de la première et de la deuxième exécution. Je parie que la deuxième exécution serait encore plus rapide, en raison de la mise en cache dans le système d'exploitation.

2voto

Wayne Points 3098

En bref, l'IL est compilé en JIT pour chaque invocation du programme et est maintenu dans les pages de code de l'espace d'adressage du processus. Voir le chapitre 1 de Richter pour une bonne couverture du modèle d'exécution .NET.

1voto

Arra Avakian Points 11

Oui, NGEN.EXE placera une version compilée JIT d'un exécutable .NET dans le GAC, même si la version MSIL n'est pas là. J'ai essayé, mais sans succès. Je pense que, à moins que la version MSIL originale ne se trouve également dans le GAC et ne soit chargée à partir de là, la version JIT dans le GAC ne peut pas être utilisée. de là, la version JIT dans le GAC ne sera pas utilisée. Je pense également que les compilations JIT à la volée ( pas NGEN) ne sont jamais mis en cache, ils occupent uniquement la processus uniquement.

C'est ce que je crois en lisant la doc MS et en me basant sur diverses expériences. Je serais heureux de recevoir soit une confirmation ou une réfutation de mes affirmations de la part de ceux "qui savent".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X