Что такое Java -XX: + UseMembar параметр
Я вижу этот параметр во всех типах мест (форумах и т.д.), а общий ответ - высококонкурентным серверам. Тем не менее, я не могу найти официальную документацию с солнца, объясняющую, что она делает. Кроме того, был ли он добавлен в Java 6 или он существовал в Java 5?
(BTW, хорошее место для многих параметров виртуальной машины Hotspot эта страница)
Обновление: Java 5 не загружается с этим параметром.
Ответы
Ответ 1
Чтобы оптимизировать производительность, JVM использует "псевдо-барьер памяти" в коде, чтобы действовать как команда фехтования при синхронизации на нескольких процессорах. Можно вернуться к "истинной" инструкции по защите памяти, но это может иметь заметное (и плохое) влияние на производительность.
Использование -XX:+UseMembar
приводит к тому, что виртуальная машина возвращается к действительным инструкциям по памяти. Первоначально этот параметр предполагался временно существовать в качестве механизма проверки новой псевдобарьерной логики, но оказалось, что новый код барьера псевдо-памяти ввел некоторые проблемы синхронизации. Я считаю, что теперь они исправлены, но до тех пор, пока они не были, приемлемым способом обойти эти проблемы было использование восстановленного флага.
Ошибка была введена в 1.5, и я считаю, что флаг существует в 1.5 и 1.6.
У меня есть google-fu'ed это из разных списков рассылки и ошибок JVM:
Ответ 2
butterchicken только объясняет половину истории, я хотел бы увеличить подробности до ответа kmatveev. Да, опция предназначена для изменений состояния потока, и (псевдо) барьеры памяти используются, чтобы гарантировать, что изменение видно из других потоков, особенно потока VM. Состояния резьбы, используемые в OpenJDK6, следующие:
// _thread_new : Just started, but not executed init. code yet (most likely still in OS init code)
// _thread_in_native : In native code. This is a safepoint region, since all oops will be in jobject handles
// _thread_in_vm : Executing in the vm
// _thread_in_Java : Executing either interpreted or compiled Java code (or could be in a stub)
...
_thread_blocked = 10, // blocked in vm
Без опции UseMembar, в Linux, Hotspot использует сериализацию памяти вместо инструкции памяти. Всякий раз, когда происходит переход состояния потока, поток записывает в адрес памяти в памяти сериализует страницу с изменчивым указателем. Когда поток VM должен смотреть на современное состояние всех потоков, VM изменяет биты защиты для страницы сериализации памяти только для чтения, а затем восстанавливает ее для чтения/записи для изменения состояния сериализации. Более подробный механизм представлен на следующей странице:
http://home.comcast.net/~pjbishop/Dave/Asymmetric-Dekker-Synchronization.txt
Ответ 3
UseMembar определяет, следует ли использовать инструкции membar строго, заставляя все действия памяти завершить до продолжения.
В основном он останавливает обработку обработчиков с задержкой в обработке памяти из-за взаимодействия с кодом.
Это обычно замедляет работу и не требуется для современных виртуальных машин для подавляющего большинства кодов.
Иногда вы сталкиваетесь с проблемами, когда код ДОЛЖЕН быть потокобезопасным, но не потому, что использование команды membar отсутствует. В этих случаях вы можете включить это, чтобы работать с таким кодом, не переключаясь на однопоточность или беспорядок с кодовым упорядочением, чтобы предотвратить проблему.
JVM, как правило, хорош в обнаружении кода, который вызовет проблемы, и либо вставьте membar, либо оптимизируйте перегруппировку кода JIT, чтобы предоставить время для завершения операций с памятью. Фактически, в моем веб-поиске по этой теме я нашел только один пример ошибки и был исправлен в последних версиях версий Oracle и OpenJRE для JVM hotspot.
В качестве примечания для архитектуры ARM эта опция по-прежнему включена, поскольку альтернативные оптимизации (известные как оптимизация псевдо-мембара) еще не применяются, и поэтому они могут быть очень ошибочными без инструкций membar.
Ответ 4
Я не согласен с ответом от butterchicken. Эта страница
http://www.md.pp.ru/~eu/jdk6options.html
говорит, что этот флаг вызывает барьеры памяти, которые будут выдаваться, тогда поток изменяет его состояние (от RUNNABLE до WAITING или BLOCKED, например).