为什么这种方法成为热点?

sig*_*ned 8 java optimization performance visualvm

我正在写一个(简单!)线性代数库.在执行矩阵乘法,一个VisualVM的性能样品是告诉我,该算法在下面的方法乘以大矩阵(5K X 120K)时花费的它的时间为85%("自我时间",具体地):

public double next() {
    double result;

    if(hasNext())
        result = vis[i++].next();
    else
        throw new IllegalStateException("No next value");

    return result;
}
Run Code Online (Sandbox Code Playgroud)

没有太多细节(抱歉,我不能共享更多代码),这个方法是next()矩阵的"迭代器" 的方法.(你可以把这个方法住在如由单独的列迭代器,这都存放在一排迭代器之类的vis).我并不感到惊讶,这种方法被调用了很多,因为它是一个迭代器,但我感到惊讶的是,该程序花了很多时间这个方法上.这种方法做得不多,为什么要花时间在这里呢?

以下是我要问的具体问题:

  1. 我正在打击VisualVM的某些"陷阱"吗?例如,JIT是否会以某种方式混淆VisualVM,导致VisualVM将时间归因于错误的方法?
  2. 为什么该计划会花时间在这里?该方法并没有做太多.具体而言,我不认为因为缓存的效果解释这个问题vis阵列要小于乘以矩阵的数据.

如果它有用,这里是我上面粘贴的方法的jad反汇编:

public double next()
{
    double result;
    if(hasNext())
//*   0    0:aload_0         
//*   1    1:invokevirtual   #88  <Method boolean hasNext()>
//*   2    4:ifeq            32
        result = vis[i++].next();
//    3    7:aload_0         
//    4    8:getfield        #42  <Field VectorIterator[] vis>
//    5   11:aload_0         
//    6   12:dup             
//    7   13:getfield        #28  <Field int i>
//    8   16:dup_x1          
//    9   17:iconst_1        
//   10   18:iadd            
//   11   19:putfield        #28  <Field int i>
//   12   22:aaload          
//   13   23:invokeinterface #72  <Method double VectorIterator.next()>
//   14   28:dstore_1        
    else
//*  15   29:goto            42
        throw new IllegalStateException("No next value");
//   16   32:new             #89  <Class IllegalStateException>
//   17   35:dup             
//   18   36:ldc1            #91  <String "No next value">
//   19   38:invokespecial   #93  <Method void IllegalStateException(String)>
//   20   41:athrow          
    return result;
//   21   42:dload_1         
//   22   43:dreturn         
}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助!

sig*_*ned 10

我发现这个方法看起来像一个热点,因为VisualVM被指示在其分析中忽略JRE中的方法.在那些"被忽略"的方法中花费的时间(表面上)被卷入调用堆栈的最顶层非忽略条目的自身时间.

下面是VisualVM中的设置屏幕,包括使数据错误的"不要配置文件包"设置.要调整"忽略类"设置,您必须(1)单击红色突出显示的"设置"复选框,然后(2)调整以蓝色突出显示的类设置.

VisualVM设置屏幕

根据你正在做的事情,至少不要忽略java.*javax.*包可能是有意义的.