Где скомпилированный код JIT.NET кэшируется?

A. СЕТЕВАЯ программа сначала компилируется в код MSIL. Когда это будет выполняться, JIT-компилятор скомпилирует его в собственный машинный код.

Я задаюсь вопросом:

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

46
задан smwikipedia 17 August 2015 в 15:38
поделиться

5 ответов

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

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

Диски медленные. SSD - очевидное решение.

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

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

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

73
ответ дан 26 November 2019 в 20:22
поделиться

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

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

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

7
ответ дан 26 November 2019 в 20:22
поделиться

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

Однако, в то время как в настольной\серверной версии фреймворка нет кэширования (кроме дискового кэширования ОС), в другой версии фреймворка есть кэширование машинного кода JIT.

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

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

Ссылка: We Believe in Sharing

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

11
ответ дан 26 November 2019 в 20:22
поделиться

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

2
ответ дан 26 November 2019 в 20:22
поделиться

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

1
ответ дан 26 November 2019 в 20:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: