什么是Java的-XX:+ usembar参数

时间:2023-01-07 17:19:16

I see this parameter in all kinds of places (forums, etc.) and the common answer it help highly concurrent servers. Still, I cannot find an official documentation from sun explaining what it does. Also, was it added in Java 6 or did it exist in Java 5?

我在各种各样的地方(论坛等)都看到了这个参数,常见的答案是它可以帮助高度并发的服务器。不过,我还是找不到sun提供的官方文档来解释它的功能。此外,它是在Java 6中添加的还是在Java 5中存在的?

(BTW, a good place for many hotspot VM parameters is this page)

(顺便说一句,许多热点VM参数的好地方是这个页面)

Update: Java 5 does not boot with this parameter.

更新:Java 5没有使用此参数引导。

4 个解决方案

#1


12  

In order to optimise performance, the JVM uses a "pseudo memory barrier" in code to act as a fencing instruction when synchronizing across multiple processors. It is possible to revert back to a "true" memory barrier instruction, but this can have a noticeable (and bad) effect upon performance.

为了优化性能,JVM在代码中使用“伪内存屏障”,在跨多个处理器同步时充当击剑指令。恢复到“真正的”内存屏障指令是可能的,但是这可能会对性能产生明显的(和坏的)影响。

The use of -XX:+UseMembar causes the VM to revert back to true memory barrier instructions. This parameter was originally intended to exist temporarily as a verification mechanism of the new pseudo-barrier logic, but it turned out that the new pseudo-memory barrier code introduced some synchronization issues. I believe these are now fixed, but until they were, the acceptable way to get around these issues was to use the reinstated flag.

使用-XX:+ usembar将导致VM返回到真正的内存屏障指令。这个参数原本打算作为新的伪屏障逻辑的验证机制暂时存在,但新的伪内存屏障代码引入了一些同步问题。我认为这些问题现在已经得到了解决,但在这些问题得到解决之前,可以接受的方法是使用恢复的标志。

The bug was introduced in 1.5, and I believe the flag exists in 1.5 and 1.6.

这个bug是在1.5中引入的,我认为这个标志存在于1.5和1.6中。

I've google-fu'ed this from a variety of mailing lists and JVM bugs:

我从各种邮件列表和JVM bug中搜索到这一点:

#2


4  

butterchicken only explains half of the story, I would like to augment more detail to kmatveev's answer. Yes, the option is for thread state changes, and (pseudo) memory barriers are used to ensure that the change is visible from other threads, especially VM thread. Thread states used in OpenJDK6 are as follows:

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   

Without UseMembar option, in Linux, Hotspot uses memory serialize page instead of memory barrier instruction. Whenever a thread state transition happens, the thread writes to a memory address in memory serialize page with volatile pointer. When the VM thread needs to look at up-to-date state of all the threads, VM changes the protection bits for the memory serialize page to read only and then recovers it to read/write to serialize state changes. More detailed mechanism is introduced in the following page:

没有UseMembar选项,在Linux中,Hotspot使用内存序列化页面而不是内存障碍指令。每当线程状态转换发生时,线程都使用volatile指针写入内存串行化页面中的内存地址。当VM线程需要查看所有线程的最新状态时,VM将内存序列化页面的保护位更改为只读,然后恢复为读/写以序列化状态更改。下一页将介绍更详细的机制:

http://home.comcast.net/~pjbishop/Dave/Asymmetric-Dekker-Synchronization.txt

http://home.comcast.net/ pjbishop /戴夫/ Asymmetric-Dekker-Synchronization.txt

#3


2  

UseMembar determines whether or not to use membar instructions in a strict manner, forcing all memory actions to complete before continuing.

usembar决定是否严格地使用membar指令,强制在继续之前完成所有内存操作。

It basically stops the processor's delayed memory handling optimizations from messing with the code is handled.

它基本上阻止了处理器的延迟内存处理优化,避免了处理代码的混乱。

This generally slows things down, and isn't necessary on modern VMs for the vast majority of code.

这通常会使事情变慢,而且对于绝大多数代码来说,在现代虚拟机中并不是必需的。

Occasionally you run into issues where code SHOULD be thread-safe but isn't because the lack of membar instruction use. In these cases you can turn this on to get such code to work without switching to single-threading or messing around with the code's ordering to prevent the issue.

有时您会遇到代码应该是线程安全的问题,但这并不是因为缺少membar指令的使用。在这些情况下,您可以打开它以使此类代码正常工作,而不必切换到单线程,也不必为了防止问题而打乱代码的顺序。

The JVM is generally good at detecting code that will cause problems and either insert a membar or do a JIT code rearrange optimization to provide time for the memory operations to complete. In fact, in my web search on the topic, I only found one example of the bug, and it was fixed in recent versions of both the Oracle and OpenJRE versions of the hotspot JVM.

JVM通常擅长检测会导致问题的代码,或者插入一个membar,或者做一个JIT代码重新安排优化,以便为内存操作提供完成的时间。事实上,在我关于这个主题的web搜索中,我只找到了一个bug示例,并且它在hotspot JVM的Oracle和OpenJRE版本的最新版本中都得到了修复。

As a note, for ARM architectures this option still defaults to on, because alternate optimizations (known as psuedo-membar optimizations) have not been applied yet, and thus it is subject to be very buggy without membar instructions.

值得注意的是,对于ARM架构,这个选项仍然默认为on,因为还没有应用替代优化(称为psuedo-membar优化),因此在没有membar指令的情况下,这个选项很容易出错。

#4


1  

I don't agree with answer from butterchicken. This page http://www.md.pp.ru/~eu/jdk6options.html says that this flag causes memory barriers to be issued then thread changes it's state (from RUNNABLE to WAITING or to BLOCKED, for example).

我不同意butterchicken公司的回答。这个页面http://www.md.p .ru/~eu/jdk6options.html说,这个标志会导致内存障碍,然后线程会改变它的状态(例如,从RUNNABLE到等待或阻塞)。

#1


12  

In order to optimise performance, the JVM uses a "pseudo memory barrier" in code to act as a fencing instruction when synchronizing across multiple processors. It is possible to revert back to a "true" memory barrier instruction, but this can have a noticeable (and bad) effect upon performance.

为了优化性能,JVM在代码中使用“伪内存屏障”,在跨多个处理器同步时充当击剑指令。恢复到“真正的”内存屏障指令是可能的,但是这可能会对性能产生明显的(和坏的)影响。

The use of -XX:+UseMembar causes the VM to revert back to true memory barrier instructions. This parameter was originally intended to exist temporarily as a verification mechanism of the new pseudo-barrier logic, but it turned out that the new pseudo-memory barrier code introduced some synchronization issues. I believe these are now fixed, but until they were, the acceptable way to get around these issues was to use the reinstated flag.

使用-XX:+ usembar将导致VM返回到真正的内存屏障指令。这个参数原本打算作为新的伪屏障逻辑的验证机制暂时存在,但新的伪内存屏障代码引入了一些同步问题。我认为这些问题现在已经得到了解决,但在这些问题得到解决之前,可以接受的方法是使用恢复的标志。

The bug was introduced in 1.5, and I believe the flag exists in 1.5 and 1.6.

这个bug是在1.5中引入的,我认为这个标志存在于1.5和1.6中。

I've google-fu'ed this from a variety of mailing lists and JVM bugs:

我从各种邮件列表和JVM bug中搜索到这一点:

#2


4  

butterchicken only explains half of the story, I would like to augment more detail to kmatveev's answer. Yes, the option is for thread state changes, and (pseudo) memory barriers are used to ensure that the change is visible from other threads, especially VM thread. Thread states used in OpenJDK6 are as follows:

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   

Without UseMembar option, in Linux, Hotspot uses memory serialize page instead of memory barrier instruction. Whenever a thread state transition happens, the thread writes to a memory address in memory serialize page with volatile pointer. When the VM thread needs to look at up-to-date state of all the threads, VM changes the protection bits for the memory serialize page to read only and then recovers it to read/write to serialize state changes. More detailed mechanism is introduced in the following page:

没有UseMembar选项,在Linux中,Hotspot使用内存序列化页面而不是内存障碍指令。每当线程状态转换发生时,线程都使用volatile指针写入内存串行化页面中的内存地址。当VM线程需要查看所有线程的最新状态时,VM将内存序列化页面的保护位更改为只读,然后恢复为读/写以序列化状态更改。下一页将介绍更详细的机制:

http://home.comcast.net/~pjbishop/Dave/Asymmetric-Dekker-Synchronization.txt

http://home.comcast.net/ pjbishop /戴夫/ Asymmetric-Dekker-Synchronization.txt

#3


2  

UseMembar determines whether or not to use membar instructions in a strict manner, forcing all memory actions to complete before continuing.

usembar决定是否严格地使用membar指令,强制在继续之前完成所有内存操作。

It basically stops the processor's delayed memory handling optimizations from messing with the code is handled.

它基本上阻止了处理器的延迟内存处理优化,避免了处理代码的混乱。

This generally slows things down, and isn't necessary on modern VMs for the vast majority of code.

这通常会使事情变慢,而且对于绝大多数代码来说,在现代虚拟机中并不是必需的。

Occasionally you run into issues where code SHOULD be thread-safe but isn't because the lack of membar instruction use. In these cases you can turn this on to get such code to work without switching to single-threading or messing around with the code's ordering to prevent the issue.

有时您会遇到代码应该是线程安全的问题,但这并不是因为缺少membar指令的使用。在这些情况下,您可以打开它以使此类代码正常工作,而不必切换到单线程,也不必为了防止问题而打乱代码的顺序。

The JVM is generally good at detecting code that will cause problems and either insert a membar or do a JIT code rearrange optimization to provide time for the memory operations to complete. In fact, in my web search on the topic, I only found one example of the bug, and it was fixed in recent versions of both the Oracle and OpenJRE versions of the hotspot JVM.

JVM通常擅长检测会导致问题的代码,或者插入一个membar,或者做一个JIT代码重新安排优化,以便为内存操作提供完成的时间。事实上,在我关于这个主题的web搜索中,我只找到了一个bug示例,并且它在hotspot JVM的Oracle和OpenJRE版本的最新版本中都得到了修复。

As a note, for ARM architectures this option still defaults to on, because alternate optimizations (known as psuedo-membar optimizations) have not been applied yet, and thus it is subject to be very buggy without membar instructions.

值得注意的是,对于ARM架构,这个选项仍然默认为on,因为还没有应用替代优化(称为psuedo-membar优化),因此在没有membar指令的情况下,这个选项很容易出错。

#4


1  

I don't agree with answer from butterchicken. This page http://www.md.pp.ru/~eu/jdk6options.html says that this flag causes memory barriers to be issued then thread changes it's state (from RUNNABLE to WAITING or to BLOCKED, for example).

我不同意butterchicken公司的回答。这个页面http://www.md.p .ru/~eu/jdk6options.html说,这个标志会导致内存障碍,然后线程会改变它的状态(例如,从RUNNABLE到等待或阻塞)。