<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F</id>
	<title>JIT-компиляция - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F"/>
	<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F&amp;action=history"/>
	<updated>2026-07-16T23:24:04Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://camokathomelab.servebeer.com/mediawiki/index.php?title=JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F&amp;diff=45895&amp;oldid=prev</id>
		<title>imported&gt;Gromolyak: /* Описание */</title>
		<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F&amp;diff=45895&amp;oldid=prev"/>
		<updated>2026-02-05T02:15:36Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Описание&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{falseredirect|Динамическая компиляция}}&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;JIT-компиляция&amp;#039;&amp;#039;&amp;#039; ({{lang-en|just-in-time}}, компиляция «точно в нужное время»), &amp;#039;&amp;#039;&amp;#039;динамическая компиляция&amp;#039;&amp;#039;&amp;#039; ({{lang-en|dynamic translation}}) — технология увеличения производительности программных систем, использующих [[байт-код]], путём компиляции байт-кода в [[машинный код]] или в другой формат непосредственно во время работы программы. Таким образом достигается высокая скорость выполнения по сравнению с интерпретируемым байт-кодом&amp;lt;ref&amp;gt;[https://books.google.ru/books?id=gwxBt1wHsasC&amp;amp;pg=PA12&amp;amp;dq=byte-code Core Java: An Integrated Approach] {{Wayback|url=https://books.google.ru/books?id=gwxBt1wHsasC&amp;amp;pg=PA12&amp;amp;dq=byte-code|date=20170827212037}}, 2008, ISBN 9788177228366, Dreamtech Press, 2008. p.12&amp;lt;/ref&amp;gt; (сравнимая с компилируемыми языками) за счёт увеличения потребления памяти (для хранения результатов компиляции) и затрат времени на компиляцию. Технология JIT базируется на двух более ранних идеях, касающихся среды выполнения: &amp;#039;&amp;#039;[[AOT-компиляция|компиляции байт-кода]]&amp;#039;&amp;#039; и &amp;#039;&amp;#039;динамической компиляции&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Так как JIT-компиляция является, по сути, одной из форм динамической компиляции, она позволяет применять такие технологии, как [[адаптивная оптимизация]] и [[динамическая рекомпиляция]]. Благодаря этому JIT-компиляция может показывать лучшие результаты в плане производительности, чем статическая компиляция. [[Интерпретатор|Интерпретация]] и JIT-компиляция особенно хорошо подходят для [[Динамический язык программирования|динамических языков программирования]], при этом среда исполнения справляется с [[Область видимости#Лексические vs. динамические области видимости|поздним связыванием типов]] и гарантирует безопасность исполнения.&lt;br /&gt;
&lt;br /&gt;
Проекты [[Low Level Virtual Machine|LLVM]], [[GNU Lightning]]&amp;lt;ref&amp;gt;{{Cite web |url=https://www.gnu.org/software/lightning/ |title=GNU lightning — GNU Project — Free Software Foundation (FSF) |access-date=2017-08-27 |archive-date=2017-09-19 |archive-url=https://web.archive.org/web/20170919115423/http://www.gnu.org/software/lightning/ |url-status=live }}&amp;lt;/ref&amp;gt;, [[libJIT]] (часть проекта [[DotGNU]]) и [[PyPy|RPython]] (часть проекта [[PyPy]]) могут быть использованы для создания JIT-интерпретаторов любого скриптового языка.&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации ==&lt;br /&gt;
JIT-компиляция может быть применена как ко всей программе, так и к её отдельным частям. Например, текстовый редактор может на лету компилировать регулярные выражения для более быстрого поиска по тексту. С [[AOT-компиляция|AOT-компиляцией]] такое сделать не представляется возможным для случаев, когда данные предоставляются во время исполнения программы, а не в момент компиляции. JIT используется в реализациях [[Java]] (JRE), [[JavaScript]], [[.NET Framework]], в одной из реализаций Python — [[PyPy]].&amp;lt;ref&amp;gt;Benjamin Peterson — [http://pypy.org/ PyPy] {{Wayback|url=http://pypy.org/ |date=20080512025315 }}&amp;lt;/ref&amp;gt; Существующие наиболее распространённые интерпретаторы языков [[PHP]], [[Ruby]], [[Perl]], [[Python]] и им подобных имеют ограниченные или неполные JIT.&lt;br /&gt;
&lt;br /&gt;
Большинство реализаций JIT имеет последовательную структуру: сначала приложение компилируется в байт-код виртуальной машины среды исполнения (AOT-компиляция), а потом JIT компилирует байт-код непосредственно в машинный код. В итоге при запуске приложения тратится лишнее время, что впоследствии компенсируется более быстрой его работой.&lt;br /&gt;
&lt;br /&gt;
== Описание ==&lt;br /&gt;
В языках, таких как [[Java]], [[PHP]], [[C Sharp|C#]], [[Lua]], [[Perl]], [[CLISP|GNU CLISP]], исходный код транслируется в одно из [[Промежуточное представление|промежуточных представлений]], называемое [[байт-код]]ом. Байт-код не является машинным кодом какого-либо конкретного процессора и может переноситься на различные компьютерные архитектуры и исполняться точно так же. Байт-код интерпретируется (исполняется) [[Виртуальная машина|&amp;#039;&amp;#039;виртуальной машиной&amp;#039;&amp;#039;]]. JIT читает байт-код из некоторых секторов (редко сразу из всех) и компилирует их в машинный код. Этим сектором может быть файл, функция или любой фрагмент кода. Единожды скомпилированный код может кэшироваться и в дальнейшем повторно использоваться без перекомпиляции.&lt;br /&gt;
&lt;br /&gt;
Динамически компилируемая среда — это среда, в которой компилятор может вызываться приложением во время выполнения. Например, большинство реализаций [[Common Lisp]] содержит функцию &amp;lt;code&amp;gt;compile&amp;lt;/code&amp;gt;, которая может создать функцию во время выполнения; в Python это функция &amp;lt;code&amp;gt;eval&amp;lt;/code&amp;gt;. Это удобно для программиста, так как он может контролировать, какие части кода действительно подлежат компиляции. Также с помощью этого приёма можно компилировать динамически сгенерированный код, что в некоторых случаях приводит даже к лучшей производительности, чем реализация в статически скомпилированном коде. Однако стоит помнить, что подобные функции могут быть опасны, особенно когда данные передаются из недоверенных источников.&amp;lt;ref&amp;gt;[http://habrahabr.ru/post/221937/ И снова про опасность eval()] {{Wayback|url=http://habrahabr.ru/post/221937/ |date=20140913211238 }}, habrahabr&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Основная цель использования JIT — достичь и превзойти производительность статической компиляции, сохраняя при этом преимущества динамической компиляции:&lt;br /&gt;
* Большинство тяжеловесных операций, таких, как [[парсинг]] исходного кода и выполнение базовых оптимизаций, происходит во время компиляции (до развёртывания), в то время как компиляция в машинный код из байт-кода происходит быстрее, чем из исходного кода.&lt;br /&gt;
* Байт-код более переносим (в отличие от машинного кода).&lt;br /&gt;
* Среда может контролировать выполнение байт-кода после компиляции, поэтому приложение может быть запущено в [[Песочница (безопасность)|песочнице]] (для нативных программ такая возможность тоже существует, но реализация данной технологии сложнее).&lt;br /&gt;
* Компиляторы из байт-кода в машинный код легче в реализации, так как большинство работы по оптимизации уже было проделано компилятором.&lt;br /&gt;
JIT, как правило, эффективней, чем интерпретация кода. К тому же в некоторых случаях JIT может показывать большую производительность по сравнению со статической компиляцией за счёт оптимизаций, возможных только во время исполнения:&lt;br /&gt;
# Компиляция может осуществляться непосредственно для целевого процессора и операционной системы, на которой запущено приложение. Например, JIT может использовать векторные [[SSE2]] расширения процессора, если он обнаружит их поддержку.&lt;br /&gt;
# Среда может собирать статистику о работающей программе и производить оптимизации с учётом этой информации. Некоторые статические компиляторы также могут принимать на вход информацию о предыдущих запусках приложения.&lt;br /&gt;
# Среда может делать глобальные оптимизации кода (например, встраивание библиотечных функций в код) без потери преимуществ динамической компиляции и без [[Накладные расходы (программирование)|накладных расходов]], присущих статическим компиляторам и [[компоновщик]]ам.&lt;br /&gt;
# Более простое перестраивание кода для лучшего использования [[Кэш процессора|кэша]].&lt;br /&gt;
&lt;br /&gt;
== Задержка при запуске, средства борьбы с ней ==&lt;br /&gt;
Типичная причина задержки при запуске JIT-компилятора — расходы на загрузку среды и компиляцию приложения в машинный код. В общем случае, чем лучше и чем больше оптимизаций выполняет JIT, тем больше получается задержка. Поэтому разработчикам JIT приходится искать компромисс между качеством генерируемого кода и временем запуска. Однако, часто оказывается так, что [[Узкое место|узким местом]] в процессе компиляции оказывается не сам процесс компиляции, а задержки системы ввода-вывода (так, например, &amp;#039;&amp;#039;rt.jar&amp;#039;&amp;#039; в [[Java Virtual Machine]] (JVM) имеет размер 40 МБ, и поиск метаданных в нём занимает достаточно большое количество времени).&lt;br /&gt;
&lt;br /&gt;
Ещё одно средство оптимизации — компилировать только те участки приложения, которые используются чаще всего. Этот подход реализован в [[PyPy]] и [[HotSpot]] Java Virtual Machine компании [[Sun Microsystems]].&lt;br /&gt;
&lt;br /&gt;
В качестве эвристики может использоваться счётчик запусков участков приложения, размер байт-кода или детектор циклов.&lt;br /&gt;
&lt;br /&gt;
Порой достаточно сложно найти правильный компромисс. Так, например, Sun’s Java Virtual Machine имеет два режима работы — клиент и сервер. В режиме клиента количество компиляций и оптимизаций минимально для более быстрого запуска, в то время как в режиме сервера достигается максимальная производительность, но из-за этого увеличивается время запуска.&lt;br /&gt;
&lt;br /&gt;
Ещё одна техника, называемая pre-JIT, компилирует код до запуска. Преимуществом данной техники является уменьшенное время запуска, в то же время недостатком является плохое качество скомпилированного кода по сравнению с runtime JIT.&lt;br /&gt;
&lt;br /&gt;
== История ==&lt;br /&gt;
Самую первую реализацию JIT можно отнести к LISP, написанную McCarthy в [[1960 год]]у&amp;lt;ref&amp;gt;Aycock 2003, 2. JIT Compilation Techniques, 2.1 Genesis, p. 98.&amp;lt;/ref&amp;gt;. В его книге &amp;#039;&amp;#039;Recursive functions of symbolic expressions and their computation by machine, Part I&amp;#039;&amp;#039; он упоминает функции, компилируемые во время выполнения, тем самым избавив от надобности вывода работы компилятора на [[перфокарты]].&lt;br /&gt;
&lt;br /&gt;
Другой ранний пример упоминания JIT можно отнести к [[Кен Томпсон|Кену Томпсону]], который в [[1968 год]]у впервые применил [[регулярные выражения]] для [[Сопоставление с образцом|поиска подстрок]] в текстовом редакторе [[QED (текстовый редактор)|QED]]. Для ускорения алгоритма Томпсон реализовал компиляцию регулярных выражений в машинный код [[IBM 704|IBM 7094]].&lt;br /&gt;
&lt;br /&gt;
Метод получения скомпилированного кода был предложен Митчелом в [[1970 год]]у, когда он реализовал экспериментальный язык &amp;#039;&amp;#039;LC&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039;.&amp;lt;ref&amp;gt;Aycock 2003, 2. JIT Compilation Techniques, 2.2 LC², p. 98-99.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Mitchell, J.G. (1970). &amp;#039;&amp;#039;The design and construction of flexible and efficient interactive programming systems&amp;#039;&amp;#039;.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Smalltalk]] (1983) был пионером в области JIT-технологий. Трансляция в машинный код выполнялась по требованию и кэшировалась для дальнейшего использования. Когда память кончалась, система могла удалить некоторую часть кэшированного кода из оперативной памяти и восстановить его, когда он снова потребуется. Язык программирования [[Self]] некоторое время был самой быстрой реализацией Smalltalk и работал всего лишь в два раза медленней [[Си (язык программирования)|C]], будучи полностью объектно-ориентированным.&lt;br /&gt;
&lt;br /&gt;
Self был заброшен Sun, но исследования продолжились в рамках языка Java. Термин «Just-in-time компиляция» был заимствован из производственного термина «Точно в срок» и популяризован [[Гослинг, Джеймс|Джеймсом Гослингом]], использовавшим этот термин в 1993.&amp;lt;ref&amp;gt;Aycock &amp;amp; 2003 2.14 Java, p. 107, footnote 13.&amp;lt;/ref&amp;gt; В данный момент JIT используется почти во всех реализациях Java Virtual Machine.&lt;br /&gt;
&lt;br /&gt;
Также большой интерес представляет диссертация, защищённая в 1994 году в Университете ETH (Швейцария, Цюрих) Михаэлем Францем «Динамическая кодогенерация — ключ к переносимому программному обеспечению»&amp;lt;ref&amp;gt;[http://oberoncore.ru/wiki/%D1%84%D1%80%D0%B0%D0%BD%D1%86_%D0%BC%D0%B8%D1%85%D0%B0%D1%8D%D0%BB%D1%8C Михаэль Франц — OberonCore] {{Wayback|url=http://oberoncore.ru/wiki/%D1%84%D1%80%D0%B0%D0%BD%D1%86_%D0%BC%D0%B8%D1%85%D0%B0%D1%8D%D0%BB%D1%8C |date=20170926122739 }}; [http://www.michaelfranz.com/ dissertation, entitled &amp;quot;Code  Generation On-The-Fly: A Key To Portable Software,&amp;quot; ] {{Wayback|url=http://www.michaelfranz.com/ |date=20170907041738 }}&amp;lt;/ref&amp;gt; и реализованная им система Juice&amp;lt;ref&amp;gt;{{Cite web |url=http://oberoncore.ru/wiki/juice |title=Juice — OberonCore |access-date=2009-11-07 |archive-date=2009-12-23 |archive-url=https://web.archive.org/web/20091223074248/http://oberoncore.ru/wiki/juice |url-status=live }}&amp;lt;/ref&amp;gt; динамической кодогенерации из переносимого семантического дерева для языка [[Оберон (язык программирования)|Оберон]]. Система Juice предлагалась как плагин для интернет-браузеров.&lt;br /&gt;
&lt;br /&gt;
== Безопасность ==&lt;br /&gt;
Так как JIT составляет исполняемый код из данных, возникает вопрос безопасности и возможных уязвимостей.&lt;br /&gt;
&lt;br /&gt;
JIT-компиляция включает в себя компиляцию исходного кода или байт-кода в машинный код и его выполнение. Как правило, результат записывается в память и исполняется сразу же, без промежуточного сохранения на диск или его вызов как отдельной программы. В современных архитектурах для повышения безопасности произвольные участки памяти [[:en:Executable space protection|не могут быть исполнены]] как машинный код ([[NX bit]]). Для корректного запуска регионы памяти должны быть предварительно помечены как исполняемые, при этом для большей безопасности флаг исполнения может ставиться только после снятия флага разрешения записи (Схема защиты W^X)&amp;lt;ref&amp;gt;[https://www.phoronix.com/scan.php?page=news_item&amp;amp;px=W-XOR-E-Firefox Write XOR Execute JIT Support Lands For Mozilla Firefox] {{Wayback|url=https://www.phoronix.com/scan.php?page=news_item&amp;amp;px=W-XOR-E-Firefox |date=20170802125757 }} / Phoronix,  4 January 2016 {{ref|en}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[AOT]]&lt;br /&gt;
* [[Двоичная трансляция]]&lt;br /&gt;
* [[HotSpot]]&lt;br /&gt;
* [[Common Language Runtime]]&lt;br /&gt;
* [[Crusoe]]&lt;br /&gt;
* [[GNU Lightning]]&lt;br /&gt;
* [[LLVM]]&lt;br /&gt;
* [[Самомодифицирующийся код]]&lt;br /&gt;
* [[Tracing just-in-time compilation]]&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
{{примечания}}&lt;br /&gt;
&lt;br /&gt;
{{Выполнение программы}}&lt;br /&gt;
[[Категория:Технологии компиляторов]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Gromolyak</name></author>
	</entry>
</feed>