Подтвердить что ты не робот

Где кешируется .NET JIT-код?

Программа .NET сначала скомпилирована в код MSIL. Когда он будет выполнен, компилятор JIT скомпилирует его в собственный машинный код.

Мне интересно:

Где хранятся эти JIT-скомпилированные машинные коды? Он хранится только в адресном пространстве процесса? Но так как второй запуск программы происходит намного быстрее, чем в первый раз, я думаю, что этот собственный код должен быть сохранен на диске где-то даже после завершения выполнения. Но где?

4b9b3361

Ответ 1

Память. Его можно кэшировать, что работа ngen.exe. Он генерирует версию сборки .ni.dll, содержащую машинный код и хранящуюся в GAC. Который автоматически загружается после этого, минуя шаг JIT.

Но это мало связано с тем, почему ваша программа запускается быстрее во второй раз. В первый раз у вас есть так называемый "холодный старт". В котором полностью доминирует время, затрачиваемое на поиск DLL на жестком диске. Во второй раз, когда у вас начался теплый старт, библиотеки DLL уже доступны в кеше файловой системы.

Диски работают медленно. SSD является очевидным исправлением.

Fwiw: это не проблема, которая является исключительной для управляемого кода. Большие неуправляемые программы с большим количеством DLL имеют его тоже. Два канонических примера, присутствующих на большинстве машин-разработчиков, - Microsoft Office и Acrobat Reader. Они обманывают. При установке они помещают "оптимизатор" в раздел "Запустить раздел реестра" или папку "Автозагрузка". Все, что делают эти оптимизаторы, это загрузить все DLL файлы, которые использует основная программа, а затем выйти. Это означает, что кеш файловой системы, когда пользователь впоследствии использует программу, запускается быстро, так как его горячий старт выполняется быстро.

Лично я нахожу это необычайно раздражающим. Потому что то, что они действительно делают, замедляет любую другую программу, которую я, возможно, захочу начать после входа в систему. Это редко Office или Acrobat. Я делаю это для удаления этих оптимизаторов, если это необходимо, когда обновление взорвано.

Вы также можете использовать этот трюк, но используйте его ответственно.

Ответ 2

Как указывали другие, код JIT'd для каждого процесса в вашем случае и не кэшируется - ускорение, которое вы наблюдаете при второй загрузке, - это кеширование OS-диска (то есть в памяти) узлы.

Однако, хотя кэширование (кроме кэширования OS-диска) отсутствует в настольной\серверной версии фреймворка, в другой версии фреймворка выполняется кэширование машинного кода JIT'd.

Интересно, что происходит в .Net Compact Framework (NETCF для Windows Phone 7). Недавние достижения показывают совместное использование некоторого кода структуры JIT'd между процессами, в которых код JIT'd действительно кэшируется. Это было в основном выполнено для повышения производительности (времени загрузки и использования памяти) в ограниченных устройствах, таких как мобильные телефоны.

Таким образом, в ответ на вопрос не существует прямого кэширования структуры кода JIT'd в настольной\серверной версии CLR, но будет в последней версии компактной структуры, то есть NETCF.

Ссылка: мы верим в общий доступ

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

Ответ 3

Скомпилированный машинный код JIT кэшируется в памяти за каждый метод, каждый раз, когда метод выполняется в первый раз. Я не думаю, что он всегда кэшируется на диск.

Вы можете обнаружить, что этот процесс быстрее загружается во второй раз, так как в первом режиме Windows кэшировала (в памяти) файлы, используемые вашим процессом (DLL, ресурсы и т.д.). Во втором прогоне нет необходимости переходить на диск, где это возможно было сделано при первом запуске.

Вы можете подтвердить это запуском NGen.exe, чтобы фактически предварительно скомпилировать машинный код для вашей архитектуры и сравнить производительность первого и вторые прогоны. Моя ставка заключается в том, что второй запуск все равно будет быстрее, из-за кэширования в ОС.

Ответ 4

Короче говоря, ИЛ скомпилирован JIT для каждого вызова программы и поддерживается на кодовых страницах адресного пространства процесса. См. Главу 1 Richter для большого охвата модели выполнения .NET.

Ответ 5

Я считаю, что скомпилированный код JIT никогда не хранится или не обменивается памятью. Повышение производительности, которое вы воспринимаете при втором выполнении сборки, связано с тем, что зависимые сборки уже находятся в памяти или кеше диска.

Ответ 6

Да, NGEN.EXE поместит JIT-компилированную версию исполняемого файла .NET в GAC, даже если версии MSIL нет. Я пробовал это, но безрезультатно. Я считаю, что если исходная версия MSIL также не находится в GAC и будет загружена оттуда, JIT-версия в GAC не будет использоваться. Я также считаю, что компиляции JIT на лету (не NGEN) никогда не кэшируются; они занимают процесс только память.

Я верю в это из чтения документа MS и из разных экспериментов. Я бы приветствовал либо подтверждение или опровержение моих утверждений от тех, "кто знает".