Java JRE致命错误:乘法过多

时间:2015-08-06 21:39:40

标签: java

我试图手动测试Math.pow()乘以“乘法”的速度,并偶然发现了这个错误:

  

Java Runtime Environment检测到致命错误:

     

EXCEPTION_ACCESS_VIOLATION(0xc0000005)at pc = 0x000000005ac46888,pid = 1508,tid = 6016

     

JRE版本:Java(TM)SE运行时环境(8.0_25-b18)(版本1.8.0_25-b18)
  Java VM:Java HotSpot(TM)64位服务器VM(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);

我知道这是非常极端的情况,但是,这仍然是有效的代码,可能发生的最糟糕的事情应该是在值中使用Inf,而不是JRE崩溃。这是oracle描述的真正标准行为,还是只是因为如果你看到它而没有人想修复它,你就是一个非常糟糕的人。

使用NetBeans 8.0.2运行记录

更新1

似乎问题在于乘数的大小。

long t = System.nanoTime();
for(int j = 0; j < 10000000; j++) {
    int i = j % 50;
    double val = i*i*i*i*i /* 256 times *i */ *i*i*i;
    sum ^= Double.doubleToLongBits(val);
}
System.out.println((System.nanoTime() - t) / 10000000);

会过得很好。

更新2

尝试使用

从控制台运行它
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

并且传递得很好,所以我认为它必须是这个特定JRE或NetBeans的问题。

2 个答案:

答案 0 :(得分:0)

这对我来说很好。 问题出在哪里?通过减少循环的乘法或数量来隔离问题。它是否适用于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);

jre1.8.0_51

输出:     

    -32067153335156736
    614

即使再乘以10次迭代也可以,但速度很慢。时间6020

答案 1 :(得分:0)

尝试使用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