Модель памяти Java - Java memory model

В Модель памяти Java описывает, как потоки в Язык программирования Java взаимодействовать через память. Вместе с описанием однопоточного выполнения кода модель памяти предоставляет семантика языка программирования Java.

Первоначальная модель памяти Java, разработанная в 1995 году, многими воспринималась как сломанная, препятствовавшая многим оптимизациям времени выполнения и не обеспечивающей достаточно надежных гарантий безопасности кода. Он был обновлен через Процесс сообщества Java, как Java Specification Request 133 (JSR-133), который вступил в силу в 2004 г., для Тигр (Java 5.0).[1][2]

Контекст

В Язык программирования Java и платформа обеспечивают нить возможности. Синхронизация между потоками, как известно, сложна для разработчиков; эта трудность усугубляется тем, что приложения Java могут работать на широком диапазоне процессоры и операционные системы. Чтобы делать выводы о поведении программы, разработчики Java решили, что они должны четко определить возможное поведение всех программ Java.

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

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

Если один поток выполняет свои инструкции не по порядку, то другой поток может увидеть тот факт, что эти инструкции были выполнены не по порядку, даже если это не повлияло на семантику первого потока. Например, рассмотрим два потока со следующими инструкциями, выполняющимися одновременно, где переменные x и y инициализируются значением 0:

Поток 1Поток 2
х = 1;int r1 = y;
у = 2;int r2 = x;

Если перестановки не выполняются, а чтение y в потоке 2 возвращает значение 2, то последующее чтение x должно возвращать значение 1, поскольку запись в x была выполнена до записи в y. Однако, если две записи переупорядочены, то чтение y может вернуть значение 2, а чтение x может вернуть значение 0.

Модель памяти Java (JMM) определяет допустимое поведение многопоточных программ и, следовательно, описывает, когда такое изменение порядка возможно. Он накладывает ограничения на время выполнения на отношения между потоками и основной памятью, чтобы добиться согласованных и надежных приложений Java. Делая это, это позволяет рассуждать о выполнении кода в многопоточной среде, даже несмотря на оптимизацию, выполняемую динамическим компилятором, процессором (ами) и кешами.

Модель памяти

Для выполнения одного потока правила просты. В Спецификация языка Java требует Виртуальная машина Java наблюдать внутри потока как если-серийный семантика. Среда выполнения (которая в данном случае обычно относится к динамическому компилятору, процессору и подсистеме памяти) может вводить любые полезные оптимизации выполнения, если результат изолированного потока гарантированно будет точно таким же, как и он. был бы, если бы все операторы выполнялись в порядке их появления в программе (также называемом программным порядком).[3]

Основная оговорка заключается в том, что как если бы серийный семантика не мешает различным потокам иметь разные представления данных. Модель памяти дает четкое руководство о том, какие значения разрешено возвращать при чтении данных. Основные правила подразумевают, что отдельные действия могут быть переупорядочены, пока как если бы серийный семантика потока не нарушается, и действия, предполагающие обмен данными между потоками, такие как получение или выпуск замок, убедитесь, что действия, которые происходят до них, видны другим потокам, которые видят их эффекты. Например, все, что происходит до снятия блокировки, будет считаться упорядоченным раньше и видимым для всего, что происходит после последующего получения этой же блокировки.[4]

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

Влияние

Модель памяти Java была первой попыткой предоставить всеобъемлющую модель памяти для популярного языка программирования.[5] Это было оправдано растущим распространением параллельных и параллельных систем и необходимостью предоставить инструменты и технологии с четкой семантикой для таких систем. С тех пор потребность в модели памяти получила более широкое признание, и аналогичная семантика была предоставлена ​​для таких языков, как C ++.[6]

Смотрите также

Рекомендации

  1. ^ Гетц, Брайан (24 февраля 2004). «Исправление модели памяти Java, часть 2». Получено 2010-10-18.
  2. ^ Джереми Мэнсон и Брайан Гетц (февраль 2004 г.). "JSR 133 (модель памяти Java) FAQ". Получено 2010-10-18. Модель памяти Java описывает, какое поведение допустимо в многопоточном коде и как потоки могут взаимодействовать через память. Он описывает взаимосвязь между переменными в программе и низкоуровневыми деталями их хранения и извлечения из памяти или регистров в реальной компьютерной системе. Он делает это таким образом, который может быть правильно реализован с использованием широкого спектра оборудования и широкого спектра оптимизаций компилятора.
  3. ^ Мэнсон, Джереми. "JSR-133 FAQ".
  4. ^ «JLS происходит до заказа».
  5. ^ Гетц, Брайан (24 февраля 2004). «Исправление модели памяти Java, часть 1». Получено 2008-02-17.
  6. ^ Бем, Ганс. «Потоки и модель памяти для C ++». Получено 2014-08-08.

внешняя ссылка