stringtranslate.com

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

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

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

Контекст

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

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

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

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

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

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

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

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

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

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

Влияние

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

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

Ссылки

  1. ^ Pugh, William (2000). «Модель памяти Java имеет фатальный изъян» (PDF) . Параллелизм: практика и опыт . 12 (6): 445–455. doi :10.1002/1096-9128(200005)12:6<445::AID-CPE484>3.0.CO;2-A . Получено 15 июля 2021 г. .
  2. ^ Гетц, Брайан (24.02.2004). "Исправление модели памяти Java, часть 2" (PDF) . IBM . Получено 18.10.2010 .
  3. ^ Джереми Мэнсон и Брайан Гетц (февраль 2004 г.). "JSR 133 (Java Memory Model) FAQ" . Получено 18 октября 2010 г. Модель памяти Java описывает, какие поведения допустимы в многопоточном коде, и как потоки могут взаимодействовать через память. Она описывает связь между переменными в программе и низкоуровневые детали их хранения и извлечения из памяти или регистров в реальной компьютерной системе. Она делает это таким образом, что может быть правильно реализована с использованием широкого спектра оборудования и широкого спектра оптимизаций компилятора.
  4. Мэнсон, Джереми. «JSR-133 FAQ».
  5. ^ "Глава 17. Потоки и блокировки". docs.oracle.com .
  6. ^ Гетц, Брайан (24.02.2004). "Исправление модели памяти Java, часть 1" (PDF) . IBM . Получено 17.02.2008 .
  7. ^ Бём, Ганс. "Потоки и модель памяти для C++" . Получено 2014-08-08 .

Внешние ссылки