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

Dav*_*itz 12 java concurrency jvm jvm-arguments

我在各种地方(论坛等)看到这个参数,它有助于高度并发的服务器.尽管如此,我还是找不到太阳的官方文件来解释它的作用.它是在Java 6中添加还是在Java 5中存在?

(BTW,许多热点VM参数的好地方是这个页面)

更新: Java 5无法使用此参数启动.

but*_*ken 12

为了优化性能,JVM在代码中使用"伪内存屏障",在跨多个处理器进行同步时充当屏蔽指令.可以恢复到"真正的"内存屏障指令,但这会对性能产生明显(和不良)的影响.

使用-XX:+UseMembar会导致VM恢复为真正的内存屏障指令.该参数最初旨在作为新伪屏障逻辑的验证机制暂时存在,但事实证明新的伪存储器屏障代码引入了一些同步问题.我相信这些现在已经修复,但在它们出现之前,解决这些问题的可接受方法是使用恢复的标志.

该错误是在1.5中引入的,我相信该标志存在于1.5和1.6中.

我已经从各种邮件列表和JVM错误中进行了google-fu'ed:


San*_*Kim 5

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   
Run Code Online (Sandbox Code Playgroud)

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

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