标签: jvm-hotspot

JIT没有优化涉及Integer.MAX_VALUE的循环

在写另一个问题的答案时,我注意到JIT优化的一个奇怪的边界情况.

以下程序不是 "Microbenchmark",也不是为了可靠地测量执行时间(如另一个问题的答案中所指出的).它仅用作MCVE来重现该问题:

class MissedLoopOptimization
{
    public static void main(String args[])
    {
        for (int j=0; j<3; j++)
        {
            for (int i=0; i<5; i++)
            {
                long before = System.nanoTime();
                runWithMaxValue();
                long after = System.nanoTime();
                System.out.println("With MAX_VALUE   : "+(after-before)/1e6);
            }
            for (int i=0; i<5; i++)
            {
                long before = System.nanoTime();
                runWithMaxValueMinusOne();
                long after = System.nanoTime();
                System.out.println("With MAX_VALUE-1 : "+(after-before)/1e6);
            }
        }
    }

    private static void runWithMaxValue()
    {
        final int n = Integer.MAX_VALUE;
        int i = …
Run Code Online (Sandbox Code Playgroud)

java jit jvm-hotspot compiler-optimization

49
推荐指数
1
解决办法
1394
查看次数

JRockit JVM与HotSpot JVM

如果有人能够提供关于两个JVM的优缺点的简要信息,因为它们都依赖于标准JVM规范.

java jvm jvm-hotspot jrockit

48
推荐指数
1
解决办法
2万
查看次数

读取Java JVM启动参数(例如-Xmx)

我试图找出是否有办法从正在运行的java进程中确定JVM启动属性.具体来说,我试图找出存储-Xmx(最大堆大小)和-XX:MaxPermSize等参数的位置.我正在运行Sun的1.6 jvm.

如果您想知道我为什么要这样做,我有许多JVM网络服务器可能正确配置也可能没有配置,我想将其添加到启动代码检查中.检查一下到处部署的java代码比手动查找和检查所有jvm启动文件要容易得多.现在,jvm配置文件的好坏不是我们构建过程的一部分,也不是检查到源代码控制.

java configuration jvm jvm-hotspot

46
推荐指数
2
解决办法
3万
查看次数

如何编写Java以允许SSE使用和边界检查消除(或其他高级优化)?

情况:

我正在优化LZF压缩算法的纯java实现,它涉及大量的byte []访问和基本的int数学,用于散列和比较.性能确实很重要,因为压缩的目标是降低I/O要求.我没有发布代码,因为它尚未清理,并且可能会进行大量重组.

问题:

  • 如何编写我的代码以允许它使用更快的SSE操作进行JIT编译到表单?
  • 我如何构造它,以便编译器可以轻松地消除数组边界检查?
  • 是否有关于特定数学运算的相对速度的广泛参考(等于正常加/减需要多少递增/递减,移位或对阵列访问的速度有多快)?
  • 我如何才能优化分支 - 最好是使用短体,或者一些长的条件语句,或者是嵌套条件的短条件语句?
  • 使用当前的1.6 JVM,在System.arraycopy击败复制循环之前必须复制多少个元素?

我已经做了什么:

在我因为过早优化而受到攻击之前:基本算法已经非常出色,但Java实现的速度不到等效C的2/3.我已经用System.arraycopy替换了复制循环,致力于优化循环并消除了un - 需要的操作.

我大量使用bit twiddling并将字节打包为整数,以实现性能,以及移位和屏蔽.

出于法律原因,我无法查看类似库中的实现,并且现有库具有过于严格的许可条款.

GOOD(已接受)答案的要求:

  • 不可接受的答案: "这个更快",没有解释为什么多少,为什么,或者没有用JIT编译器测试过.
  • 边界答案:在Hotspot 1.4之前没有经过任何测试
  • 基本答案:将提供一般规则和解释为什么它在编译器级别更快,大致更快
  • 好的答案:包括几个代码示例来演示
  • 优秀答案:拥有JRE 1.5和1.6的基准测试
  • 完美的答案:是由参与HotSpot编译器的人员完成的,可以完全解释或参考使用优化的条件,以及通常更快的速度.可能包含由HotSpot生成的java代码和示例汇编代码.

另外:如果有人有详细说明Hotspot优化和分支性能的内容的链接,那么欢迎这些.我对字节码有足够的了解,网站分析字节码而不是源代码级别的性能会有所帮助.

(编辑)局部答案:界限 - 检查消除:

这是从提供的HotSpot内部维基链接获取的:https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination

HotSpot将消除所有for循环中的边界检查,具有以下条件:

  • 数组是循环不变的(不在循环中重新分配)
  • 索引变量有一个恒定的步幅(增量/减少恒定量,如果可能的话只在一个点)
  • 数组由变量的线性函数索引.

例: int val = array[index*2 + 5]

要么: int val = array[index+9]

不: int val = array[Math.min(var,index)+7]


早期版本的代码:

这是一个示例版本.不要窃取它,因为它是H2数据库项目的未发布版本的代码.最终版本将是开源的.这是对代码的优化:H2 CompressLZF代码

从逻辑上讲,这与开发版本相同,但是它使用for(...)循环来逐步执行输入,并使用if/else循环来实现文字和反向引用模式之间的不同逻辑.它减少了阵列访问和模式之间的检查.

public int compressNewer(final byte[] in, final int inLen, final byte[] out, int …
Run Code Online (Sandbox Code Playgroud)

java optimization performance jvm-hotspot bounds-check-elimination

40
推荐指数
2
解决办法
1万
查看次数

java PrintCompilation输出:"make not entrant"和"made zombie"是什么意思

运行Java 1.6(1.6.0_03-b05)应用程序时,我添加了-XX:+PrintCompilation标志.在某些方法的输出中,特别是我知道的一些方法被大量调用,我看到了文本made not entrantmade zombie.

这些是什么意思?最好的猜测是,在重新编译该方法或具有更高优化的依赖项之前,它是一个反编译步骤.真的吗?为什么"僵尸"和"参赛者"?

例如,其中一些行之间有相当长的时间:

[... near the beginning]
42       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... much later]
42    made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
---   n   sun.misc.Unsafe::compareAndSwapObject
170       jsr166y.LinkedTransferQueue::xfer (294 bytes)
170   made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
  4%      jsr166y.LinkedTransferQueue::xfer @ 29 (294 bytes)
171       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... even later]
42    made zombie  jsr166y.LinkedTransferQueue::xfer (294 bytes)
170   made zombie  jsr166y.LinkedTransferQueue::xfer (294 bytes)
171   made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
172       jsr166y.LinkedTransferQueue::xfer (294 …
Run Code Online (Sandbox Code Playgroud)

java jit jvm-hotspot

40
推荐指数
3
解决办法
7704
查看次数

Java VM调优 - Xbatch和-Xcomp

我正在查看运行Alfresco的JVM配置选项,主要是Alfresco Wiki上的这个文档.其中一个建议是使用JVM标志和.这样做的理由是:-Xcomp-Xbatch

如果您希望Hotspot预编译类,可以添加[-Xcomp和-Xbatch].但是,这将显着增加服务器启动时间,但会突出显示以后可能遇到的缺失依赖项.

从我在其他地方读到的关于-Xcomp-Xbatch旗帜的内容,我想知道它们是否确实提供了任何好处.

  • -Xcomp 获得HotSpot以预先编译所有代码并进行最大程度的优化,从而推导出VM将通过系统的标准运行获得的任何分析.
  • -Xbatch停止后台编译,这意味着在编译完成之前导致代码被编译的线程.但是,在编译完成后,先前阻塞的线程将不会运行已编译的代码,它仍将运行解释的代码.这是Java 6(Mustang)的一个变化 - 在Mustang之前,由于-Xbatch标志的存在而被阻止编译的线程一旦编译完成就保证在编译的代码中运行.因此,我猜测-Xbatch标志的推荐是在较旧的VM上运行Alfresco的遗留物.

有人有想法吗?我倾向于摆脱这两面旗帜并依靠虚拟机来解决问题.

我想添加两件事,首先是我还没有访问Alfresco实例来测试这个,其次我不知道什么样的机器托管Alfresco而不是通过查看其他配置选项它必须是64位VM.尽管如此,我希望社区将有一些有用的输入,可能来自一般的HotSpot调整观点.

java jvm jvm-hotspot jvm-arguments

33
推荐指数
1
解决办法
9505
查看次数

无用的测试指令?

我得到了下面的汇编列表作为我的java程序的JIT编译的结果.

mov    0x14(%rsp),%r10d
inc    %r10d              

mov    0x1c(%rsp),%r8d
inc    %r8d               

test   %eax,(%r11)         ; <--- this instruction

mov    (%rsp),%r9
mov    0x40(%rsp),%r14d
mov    0x18(%rsp),%r11d
mov    %ebp,%r13d
mov    0x8(%rsp),%rbx
mov    0x20(%rsp),%rbp
mov    0x10(%rsp),%ecx
mov    0x28(%rsp),%rax    

movzbl 0x18(%r9),%edi     
movslq %r8d,%rsi          

cmp    0x30(%rsp),%rsi
jge    0x00007fd3d27c4f17 
Run Code Online (Sandbox Code Playgroud)

我对这test条指令的理解在这里没用,因为测试的主要思想是

标志SF,ZF,PF被修改,而AND的结果被丢弃.

这里我们不使用这些结果标志.

这是JIT中的错误还是我错过了什么?如果是,报告的最佳位置在哪里?谢谢!

java assembly jit jvm jvm-hotspot

33
推荐指数
1
解决办法
1194
查看次数

AES-NI内在函数默认启用?

关于AES-NI,Oracle有关Java 8的说法:

添加了硬件内在函数以使用高级加密标准(AES).UseAES和UseAESIntrinsics标志可用于为Intel硬件启用基于硬件的AES内在函数.硬件必须是2010或更新的Westmere硬件.例如,要启用硬件AES,请使用以下标志:

-XX:+UseAES -XX:+UseAESIntrinsics
Run Code Online (Sandbox Code Playgroud)

要禁用硬件AES,请使用以下标志:

-XX:-UseAES -XX:-UseAESIntrinsics
Run Code Online (Sandbox Code Playgroud)

但它并不表示默认情况下是否启用AES内在函数(对于支持它的处理器).所以问题很简单:如果处理器支持AES-NI,是否使用了AES内在函数?

奖金问题:有没有办法测试是否使用AES-NI?我想你可以根据性能来猜测,但这不是一种最佳或确定的测试方法.


对于不熟悉AES-NI内在函数的读者:它使用AES-NI指令集用预编译的机器代码替换字节代码.这是由JVM发生的,因此它不会出现在Java运行时或字节码的API中.

java cpu cryptography aes jvm-hotspot

31
推荐指数
1
解决办法
1万
查看次数

JVM如何决定JIT编译方法(将方法归类为"热门")?

我已经使用过-XX:+PrintCompilation,我知道JIT编译器的基本技术以及使用JIT编译的原因.

然而,我仍然没有发现JVM如何决定JIT编译方法,即"正确的时间来到JIT编译方法".

我是否正确地假设每个方法都开始被解释,并且只要它不被归类为"热方法"它就不会被编译?我有一些东西在脑后,我读到一个方法被认为是"热",当它执行至少10.000次(解释方法10.000次后,它将被编译),但我不得不承认我是不确定这个或我在哪里读到这个.

总结一下我的问题:

(1)只要没有将每种方法归类为"热"方法(并因此已被编译),或者即使它们不是"热门",也有理由编制方法?

(2)JVM如何将方法分为"非热"和"热"方法?执行次数?还要别的吗?

(3)如果"热"方法存在某些阈值(如执行次数),是否有Java标志(-XX:...)来设置此阈值?

java jit jvm jvm-hotspot

30
推荐指数
2
解决办法
5887
查看次数

29
推荐指数
3
解决办法
4万
查看次数