Java VisualVM 中的方法总时间

57
在Java VisualVM中,有没有显示总方法时间而不是“自身时间”的方法?(后者并不特别有用,因为它并不能告诉您方法实际运行需要多长时间。)
如果没有,是否有任何独立的免费Java分析工具可以计算总方法时间?
7个回答

56

在“快照”视图中查看跟踪数据可以看到总时间和自身时间。

按下出现在结果表格旁的“快照”按钮。这将创建一个包含“调用树”视图的新选项卡,其中会细分自身时间与总时间。 "联合"视图也提供此信息,但将屏幕空间分成了类似于标准分析视图的“热点”视图。

快照可以从标准“分析器”或“采样器”数据创建。然而,“分析器”快照只能在应用程序关闭之前创建,而“采样器”则可以随时创建。

(以上信息基于VisualVM 1.3.1)


5
这个答案是最详尽和有用的。我做了一个短的屏幕录像:http://rhnh.net/2011/08/03/profiling-clojure - Xavier Shay
Xavier,感谢你的录屏教程。它让我明白了。 - Yu Shen

7

只需对分析结果进行快照,即可获得墙钟时间和自身时间。


1

有一种简单的方法可以将例程的总时间作为墙钟执行时间的百分比(而不是毫秒)获取。只需在等待期间使用ctrl-break获取一堆堆栈快照即可。其中包含该例程的部分占用的时间百分比。准确性取决于您拍摄的快照数量。如果您只是想知道问题出在哪里,那么您不需要精确的时间测量。这里有一个简短的解释如何工作。


0
你可以使用 JProfiler 或者一些 Java agent 工具来监控方法的执行时间。在 GitHub 上有一些开源工具,比如 SimpleAPM。

0

我认为您想要了解每个方法执行所需的时间。您可以使用JETM来监控性能。

这将提供给您每个方法的进入时间,退出时间以及时间差。您将会知道哪个方法花费了多少时间。

如果您正在使用Spring,那么集成JETM就变得很容易了 http://jetm.void.fm/howto/spring_2_x_integration.html


-1
JavaAssist是一个类库,可以在不触及源代码的情况下操作Java字节码。让我们举个例子,测量执行方法所需的时间。
public class Subject {
    /**
     * Timetaken for start & end of the method
     * 
     * @throws InterruptedException
     */
    public void method2() throws InterruptedException {
        // Some business logic :)
        Thread.sleep(2000);
    }
}

为了测量执行subject.method2()所需的时间,您可以通过添加方法开头和结尾的代码来增强Subject.methods(),如下所示。
public class JavaAssist {
    public static void main(String[] args) {
        timeTaken();
    }

    public static void timeTaken() {
        try {
            ClassPool p = ClassPool.getDefault();
            CtClass cc = p.get("Subject");
            CtMethod meth2 = cc.getDeclaredMethod("method2");
            meth2.insertBefore("System.out.println(\" Start : \"+new java.util.Date());");
            meth2.insertAfter("System.out.println(\" End : \"+new java.util.Date());");
            // cc.writeFile(".");
            Class c = cc.toClass();
            Subject s = (Subject) c.newInstance();
            s.method2();
            cc.detach();
        } catch (Exception e) {
            // suppressed
        }
    }
}

输出: 开始时间:2010年5月26日,美国东部夏令时下午5:24:18 结束时间:2010年5月26日,美国东部夏令时下午5:24:20

Reference http://www.csg.is.titech.ac.jp/~chiba/javassist/tutorial/tutorial.html#read

http://www.csg.is.titech.ac.jp/~chiba/javassist/html/

文章来源: http://www.senthilb.com/2010/05/javaassist-byte-code-enhancement.html


-4

你可以使用一个

 long startTime = System.currentTimeMillis();

在开头

 long endTime = System.currentTimeMillis();

最后获取结果

 long result = endTime - startTime; //Note, part might be backwards, I don't
                                    //Remember

结束时间减去开始时间……否则你会得到像0-100=-100这样的结果,而不是100-0=100。 - TofuBeer
8
使用System.nanoTime()而不是currentTimeMillis(),因为由于操作系统中断率的影响,后者容易出错:http://blogs.sun.com/dholmes/entry/inside_the_hotspot_vm_clocks - Ivo Wetzel
2
这不是实际可行的,它会消除使用自动化工具查找瓶颈的优势。 - kpozin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接