Java JRE致命错误:乘法太多

Java JRE致命错误:乘法太多,java,Java,我试图测试Math.pow()与“手动”乘法的速度,但无意中发现了以下错误: Java运行时环境检测到一个致命错误: pc=0x000000005ac46888,pid=1508,tid=6016时的异常访问(0xc0000005) JRE版本:Java(TM)SE运行时环境(8.0_25-b18)(构建1.8.0_25-b18) Java虚拟机:Java热点(TM)64位服务器虚拟机(25.25-b02混合模式windows-amd64压缩oops) 问题帧: V[jvm.dll+0x4968

我试图测试
Math.pow()
与“手动”乘法的速度,但无意中发现了以下错误:

Java运行时环境检测到一个致命错误:

pc=0x000000005ac46888,pid=1508,tid=6016时的异常访问(0xc0000005)

JRE版本:Java(TM)SE运行时环境(8.0_25-b18)(构建1.8.0_25-b18)
Java虚拟机:Java热点(TM)64位服务器虚拟机(25.25-b02混合模式windows-amd64压缩oops)
问题帧:
V[jvm.dll+0x496888]

无法写入核心转储。默认情况下,在客户端版本的Windows上不启用小型转储

生成它的代码:

long t = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
    double val = i*i*i*i*i /* 256 times *i */ *i*i*i;
    sum ^= Double.doubleToLongBits(val);
}
System.out.println((System.nanoTime() - t) / 10000000);
并且通过得很好,所以我认为这一定是这个特定JRE或NetBeans的问题。

这对我来说很好。 你的问题出在哪里?通过减少乘法或循环数来隔离问题。它能用50次乘法吗

long sum=0;
long t = System.nanoTime();
for (int i = 1; i < 10000000; i++) {
    double val = i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i
                    *i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i
                    *i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i; 
            // set of 10 *i*i*i*i*i*i*i*i*i*i
    sum ^= Double.doubleToLongBits(val);
}
System.out.println(sum);
System.out.println((System.nanoTime() - t) / 10000000);
长和=0;
long t=System.nanoTime();
对于(int i=1;i<10000000;i++){
i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i
*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*我,我,我,我,我
*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i;
//一套10*i*i*i*i*i*i*i*i*i*i*i*i*i
sum^=双精度。双精度长比特(val);
}
系统输出打印项数(总和);
System.out.println((System.nanoTime()-t)/10000000);
jre1.8.0_51

输出: -32067153335156736 614 -32067153335156736 614


即使再乘以10次迭代也可以,但速度确实很慢。time 6020在我看来,这绝对像是一个JVM错误。这更适合作为一个bug报告,而不是一个问题。请参见尝试使用BigInteger

import java.math.BigInteger;

public class hackerrank {
    public static void main (String args[]){
        BigInteger x = new BigInteger("10000000");
        BigInteger sum = BigInteger.ZERO;
        long t = System.nanoTime();
        for (BigInteger i = BigInteger.ONE; i.compareTo(x) == -1; i = i.add(BigInteger.ONE)) {
            BigInteger j = i.remainder(new BigInteger("50"));
            BigInteger val = j.pow(256);
            sum = sum.xor(val);
        }
        System.out.println((System.nanoTime() - t) / 10000000);
    }
}

输出:4083

JRE版本将非常有用。我试着在Oracle 1.8.0_45-b15(64位)上运行它,它运行得很好。如果您使用纯
javac
编译代码并从命令行运行它,Netbeans与此问题没有关系。Netbeans只是简单地让你的程序在你要求它使用的JVM中运行变得容易。看起来像是JRE 8.0_25中的bug,在8.0_45之前一直被修复,你永远不会在值中得到
Inf
。这些是整数乘法。您将得到整数溢出和乘法的整数结果,然后转换为double。此代码在任何方面都无法与
Math.pow()
相比。不应该失败,但它做不到你想要的。我也没有得到
sum^=
部分。在问题下的评论中,我们得出结论,它发生在JRE 8.0_25上,乘法的数量也在变化。你完全没有抓住这个问题的重点。这不是关于获得原始任务的答案,而是找出为什么完全有效的代码会使JVM崩溃。此外,在BigInteger上进行测量与我所检查的内容不符,也就是说,从什么角度出发,通过扩展乘法来避免“Math.pow”不再是有益的。我想BigInteger并不完全是您的每日数字类型。 -32067153335156736 614
import java.math.BigInteger;

public class hackerrank {
    public static void main (String args[]){
        BigInteger x = new BigInteger("10000000");
        BigInteger sum = BigInteger.ZERO;
        long t = System.nanoTime();
        for (BigInteger i = BigInteger.ONE; i.compareTo(x) == -1; i = i.add(BigInteger.ONE)) {
            BigInteger j = i.remainder(new BigInteger("50"));
            BigInteger val = j.pow(256);
            sum = sum.xor(val);
        }
        System.out.println((System.nanoTime() - t) / 10000000);
    }
}