【问题标题】:Total method time in Java VisualVMJava VisualVM 中的总方法时间
【发布时间】:2010-12-25 21:50:02
【问题描述】:

在 Java VisualVM 中,有没有办法显示总方法时间,而不是“自我时间”? (后者并不是特别有用,因为它不会告诉您方法实际运行需要多少时间。)

如果没有,是否有任何独立的免费 Java 分析器可以计算总方法时间?

【问题讨论】:

    标签: java profiling visualvm


    【解决方案1】:

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

    按显示在结果表周围的“快照”按钮。这将创建一个包含“调用树”视图的新选项卡,该视图分解了自我与总时间。 “组合”视图也提供此信息,但使用类似于标准分析视图的“热点”视图分割屏幕空间。

    可以从标准的“Profiler”或“Sampler”数据创建快照。但是,“Profiler”快照只能在应用关闭之前创建,而“Sampler”快照可以随时创建。

    (以上信息基于VisualVM 1.3.1)

    【讨论】:

    【解决方案2】:

    只需对分析结果进行快照即可。您将在那里获得挂钟时间和自拍时间。

    【讨论】:

      【解决方案3】:

      有一种简单的方法可以获取例程的总时间占挂钟执行时间的百分比(而不是毫秒)。只需在等待时使用 ctrl-break 获取一堆堆栈快照。其中包含例程的部分是它所花费的时间百分比。准确性取决于您拍摄的次数。如果您只是在寻找问题所在,则不需要精确的时间测量。 Here's a short explanation of how it works.

      【讨论】:

        【解决方案4】:

        我想你想知道每个方法执行需要多少时间。您可能希望使用 JETM 来监控性能。 这将为您提供每种方法的进入时间、退出时间和时间差。您会发现哪种方法花费了多少时间。

        如果您使用的是 Spring,那么集成 JETM 将变得很容易 http://jetm.void.fm/howto/spring_2_x_integration.html

        【讨论】:

          【解决方案5】:

          你可以使用jprofiler或者一些javaagent工具来为你监控方法的执行时间。github上有一些开源工具,比如simpleAPM。

          【讨论】:

            【解决方案6】:

            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 日星期三 17:24:18 EDT 结束:2010 年 5 月 26 日星期三 17:24:20 EDT

            参考 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

            【讨论】:

              【解决方案7】:

              你可以用一个

               long startTime = System.currentTimeMillis();
              

              一开始

               long endTime = System.currentTimeMillis();
              

              最终得到结果

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

              【讨论】:

              • end - start... 否则你会得到类似的结果:0 - 100 = -100 而不是 100 - 0 = 100。
              • 使用 System.nanoTime(),currentTimeMillis() 由于操作系统中断率而容易出错:blogs.sun.com/dholmes/entry/inside_the_hotspot_vm_clocks
              • 这不实用;它消除了使用自动化工具查找瓶颈的优势。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-01-15
              • 2014-09-30
              • 1970-01-01
              • 2011-07-26
              • 1970-01-01
              相关资源
              最近更新 更多