2015-08-06 17 views
19

stavo cercando di testare la velocità di Math.pow() contro moltiplicazione "a mano" e incappato in questo errore:Java JRE errore fatale: troppi moltiplicazioni

A fatal error has been detected by the Java Runtime Environment:

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

JRE version: Java(TM) SE Runtime Environment (8.0_25-b18) (build 1.8.0_25-b18)
Java VM: Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode windows-amd64 compressed oops)
Problematic frame:
V [jvm.dll+0x496888]

Failed to write core dump. Minidumps are not enabled by default on client versions of Windows

Codice generano esso:

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); 

I capisci che questo è davvero un caso estremo, ma comunque, questo è un codice valido e la cosa peggiore che potrebbe accadere dovrebbe avere Inf nel valore, e non il crash di JRE. E 'questo comportamento standard descritto da oracle o bug che nessuno vuole risolvere solo perché se lo stai vedendo, sei davvero una persona cattiva.

Per la corsa record con NetBeans 8.0.2

UPDATE 1

Sembra problema è nella grandezza del numero moltiplicato.

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); 

passerà bene.

UPDATE 2

provato a farlo funzionare da console con

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) 

e superato bene, quindi immagino che deve essere o problema con questa specifica JRE o con NetBeans.

+0

La versione di JRE sarebbe utile. Ho provato a eseguire questo su Oracle 1.8.0_45-b15 (64 bit) e ha funzionato bene. – biziclop

+0

Con la ricerca binaria, ho determinato che la moltiplicazione di 124 'i's funziona, ma 125 restituisce l'errore sopra, almeno sul mio PC Windows 7, eseguendo Java 1.8.0_45, tramite IntelliJ. – rgettman

+1

E se compilate il codice con plain 'javac' ed eseguitelo dalla riga di comando? La versione – biziclop

risposta

1

Questo mi sembra decisamente un bug JVM. Questo è più adatto come segnalazione di bug di una domanda su SO. Vedi http://bugreport.java.com/

0

Questo funziona per me. Dove si verifica il problema? Isolare il problema riducendo le moltiplicazioni o il numero di cicli. Funziona con 50 moltiplicazioni?

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

uscita:

 -32067153335156736 
    614

Anche moltiplicando per altri 10 iterazioni funziona ma è molto lento. time 6020

+0

Nei commenti sotto la domanda abbiamo concluso che ciò avviene su JRE 8.0_25 e il numero di moltiplicazioni che variano. –

0

Provare a utilizzare 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); 
    } 
} 

di uscita: 4083

+0

Hai completamente perso il punto di questa domanda. Non si tratta di ottenere la risposta al compito originale, piuttosto che scoprire perché il codice completamente valido sta bloccando la JVM. Inoltre, la misurazione su BigInteger non segue la cosa che stavo controllando, cioè da che punto non è più utile evitare "Math.pow" espandendo la moltiplicazione. Suppongo che BigInteger non sia esattamente il tuo tipo di numero ogni giorno. –