代码之家  ›  专栏  ›  技术社区  ›  David Rabinowitz

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

  •  12
  • David Rabinowitz  · 技术社区  · 16 年前

    我在各种地方(论坛等)都看到这个参数,它的常见答案有助于高度并发的服务器。不过,我还是找不到Sun的官方文件来解释它的作用。此外,它是在Java 6中添加的还是Java 5中存在的?

    (顺便说一句,许多热点虚拟机参数的好地方是 this page )

    更新: Java 5没有用这个参数启动。

    4 回复  |  直到 10 年前
        1
  •  12
  •   Community Mohan Dere    8 年前

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

    使用 -XX:+UseMembar 使虚拟机恢复为真正的内存屏障指令。这个参数最初是作为新的伪屏障逻辑的验证机制暂时存在的,但结果表明,新的伪内存屏障代码引入了一些同步问题。我相信这些问题现在已经解决了,但在解决之前,解决这些问题的可接受方法是使用恢复的标志。

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

    我从各种邮件列表和jvm错误中找到了这个:

        2
  •  4
  •   Sangman Kim    14 年前

    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   
    

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

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

        3
  •  2
  •   Robert Wm Ruedisueli    10 年前

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

    它基本上阻止处理器的延迟内存处理优化处理代码。

    这通常会减慢速度,对于大多数代码来说,在现代虚拟机上这是不必要的。

    偶尔会遇到代码应该是线程安全的问题,但这并不是因为缺少membar指令的使用。在这些情况下,您可以打开它来让这些代码工作,而不必切换到单线程,也不必为防止出现问题而混乱代码的顺序。

    JVM通常擅长检测会导致问题的代码,插入membar或执行JIT代码重新排列优化,以提供完成内存操作的时间。事实上,在我关于这个主题的网络搜索中,我只找到了一个bug的例子,并且在Hotspot JVM的Oracle和OpenJRE版本的最新版本中修复了这个bug。

    注意,对于ARM体系结构,此选项仍然默认为打开,因为还没有应用备用优化(称为psuedo membar优化),因此如果没有membar指令,它可能会非常麻烦。

        4
  •  1
  •   kmatveev    16 年前

    我不同意毛茛的回答。本页 http://www.md.pp.ru/~eu/jdk6options.html 表示此标志导致发出内存屏障,然后线程更改其状态(例如,从可运行状态变为等待状态或阻塞状态)。

    推荐文章