2012-08-29 54 views
0

我正在使用Google卡尺在方法上运行一个非常简单的基准。我收到以下例外情况。卡尺:JVM抛出OutOfMemoryError异常

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at com.code4refernce.caliper.SimpleCaliperTest.timeStringLen(SimpleCaliperTest.java:24) 
    at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:616) 
    at com.google.caliper.SimpleBenchmark$1.run(SimpleBenchmark.java:125) 
    at com.google.caliper.TimeMeasurer.measureReps(TimeMeasurer.java:174) 
    at com.google.caliper.TimeMeasurer.warmUp(TimeMeasurer.java:62) 
    at com.google.caliper.TimeMeasurer.run(TimeMeasurer.java:122) 
    at com.google.caliper.InProcessRunner.run(InProcessRunner.java:74) 
    at com.google.caliper.InProcessRunner.run(InProcessRunner.java:49) 
    at com.google.caliper.InProcessRunner.main(InProcessRunner.java:103) 

我不明白为什么我得到这个异常。我试图增加JVM内存,然后我也得到这个异常。

基准代码如下。

package com.code4refernce.caliper; 
import java.util.Random; 
import java.util.regex.Pattern; 

import com.google.caliper.Param; 
import com.google.caliper.SimpleBenchmark; 

public class SimpleCaliperTest extends SimpleBenchmark { 
    String regex = "(\\d{3}-\\d{3}-\\d{4})|(\\d{10})"; 
    Pattern REGEX_PATTERN = Pattern.compile(regex); 

    String mdn[]; 
    Random random; 
    @Param 
    int index; 

    @Override 
    protected void setUp() { 
     random = new Random(0); 
     mdn = new String[4]; 
      mdn[0] = "098412sdfasdf8000"; 
      mdn[1] = "11345"; 
      mdn[2] = "1423567890"; 
      mdn[3] = "123-456-7890"; 
    } 


    public Boolean[] timeStringLen(int reps){ 
     Boolean results[] = new Boolean[reps]; 

     for(int i = 0; i<reps; i ++){ 

      results [i]= mdnCheckRegularMethod(mdn[index]); 
     } 
     return results; 
    } 
    public Boolean[] timeRegex(int reps){ 
     Boolean results[] = new Boolean[reps]; 
     for(int i = 0; i<reps; i ++){ 

      results[i]=mdnCheckRegEx(mdn[index]); 
     } 
     return results; 
    } 
    private boolean mdnCheckRegularMethod(String mdn){ 
     boolean result = false; 

     if(mdn.length()==10){ 
      try{ 
       Integer.parseInt(mdn); 
       result = true; 
      }catch(Exception e){ 
       result = false; 
      } 
     } 
     else if(mdn.length() == 13){ 
      byte[] bmdn = mdn.getBytes(); 
      for(int i = 0; i<bmdn.length; i++){ 
       if((i == 3 || i == 6) && bmdn[i] == '-'){} 
       else if(bmdn[i] >= '0' && bmdn[i]<='9'){} 
       else{ 
        result = false; 
        break; 
       } 
      } 
     } 
     else{ 
      result = false; 
     } 
     return result; 
    } 

    private boolean mdnCheckRegEx(String mdn){ 
     return REGEX_PATTERN.matcher(mdn).matches(); 
    } 
} 

和运行卡尺基准的主类。

package com.code4refernce.caliper; 
import com.google.caliper.Runner; 

    public class CaliperRunner { 
     public static void main(String[] args) { 
      String myargs[] = new String[2]; 
      myargs[0] = new String("-Dindex=0,1,2,3"); 
      myargs[1] = new String("-Jmemory=-Xms1024m "); 
      Runner.main(SimpleCaliperTest.class, myargs); 
     } 
    } 

我不明白这里出了什么问题。有人可以指出吗?

+0

哪一条是24号线?布尔数组或对mdnCheckRegularMethod的调用? – home

+0

Boolean [] results = new Boolean [reps]; \\ line24 – Rakesh

+1

如果您使用本机'boolean'类型进行数组初始化,该怎么办? – home

回答

1

您的方法timeStringLen(int reps)可能会调用reps高达Integer.MAX_VALUE。你可以通过-Xmx开关给你的虚拟机更多的内存,但是你最好不要分配不必要的大的阵列,它并不需要在所有:

public boolean timeStringLen(int reps){ 
    boolean result = false; 

    for(int i = 0; i<reps; i ++){ 
     result ^= mdnCheckRegularMethod(mdn[index]); 
    } 
    return result; 
} 

这做相同的工作,返回一个值的唯一原因是为了防止JIT将其全部优化。 Xoring在这里已经足够了,计算方法返回true时的情况是另一种可能性。


但最有可能有一个与你的标杆另一个问题:它的运行速度更快,那么我期望的reps用于显示高值。每次迭代的结果似乎是相同的,我猜你得到的循环优化,像

result[i] = Boolean.TRUE 

我要测量不觉得。使用类似

Random random = new Random(0); 
mdn = new String[4][1<<16]; 
for (int i=0; i<mdn.length; ++i) { 
    mdn[0][i] = String.format("%03ddsfasdf00000", random.nextInt(1000)); 
    mdn[1][i] = String.format("%04d", random.nextInt(10000)); 
    mdn[2][i] = String.format("%10d", random.nextInt((int) 1e10)); 
    mdn[3][i] = String.format("%03d-%03d-%03d", random.nextInt(1000), random.nextInt(1000), random.nextInt(1000)); 
} 

会有所帮助。

+0

感谢您的回答。我编辑了代码(查看本主题的第一篇文章)。我不知道为什么正则表达式表现不好。这里有什么不对吗? – Rakesh

+0

@Rakesh您最好创建一个新的问题,因为最初的问题已经得到解答。标题不再匹配。我会将文本复制到一个新问题中,并在此处回滚这些更改。 – maaartinus

+0

谢谢..我现在就做。 – Rakesh