java - 执行方法栈中所有方法所花费的时间

标签 java spring profiling

很多时候在编写应用程序时,我希望在 stacktrace 中分析和测量所有方法所花费的时间。我的意思是说:

Method A --> Method B --> Method C ...

A 方法在内部调用 B 并且它可能会调用另一个。我想知道在每个方法中执行所花费的时间。这样,在 Web 应用程序中,我可以准确地知道代码的哪一部分所消耗的时间百分比。

为了进一步解释,在大多数情况下,在 spring 应用程序中,我编写了一个方面,用于收集类的每个方法调用的信息。最后给了我总结。但我讨厌这样做,它重复且冗长,并且需要不断更改正则表达式以适应不同的类。相反,我想要这样:

@Monitor
public void generateReport(int id){
...
}

在方法上添加一些注释将触发检测 api 来收集此方法所用时间的所有统计信息以及以后调用的任何方法。并且当该方法退出时,它停止收集信息。我认为这应该比较容易实现。

问题是:对于一般的 Java 代码,是否有任何合理的替代方案可以让我这样做?或者任何快速收集这些信息的方法。或者甚至是用于 spring 应用程序的 spring 插件?

PS:一模一样XRebel ,它会生成代码的安全、DAO、服务等部分所用时间的精美摘要。但它要花一枚炸弹。如果负担得起,绝对应该购买。

最佳答案

你想写一个Java agent .这样的代理允许您在加载类时重新定义它。这样,您可以在不污染源代码的情况下实现一个方面。我写了一个图书馆,Byte Buddy ,这使得这相当容易。

对于您的监视器示例,您可以按如下方式使用 Byte Buddy:

new AgentBuilder.Default()
 .rebase(declaresMethod(isAnnotatedWith(Monitor.class))
 .transform( (builder, type) ->
   builder
     .method(isAnnotatedWith(Monitor.class))
     .intercept(MethodDelegation.to(MonitorInterceptor.class);
  );

class MonitorInterceptor {
  @RuntimeType
  Object intercept(@Origin String method,
                                @SuperCall Callable<?> zuper)
      throws Exception {
    long start = System.currentTimeMillis();
    try {
       return zuper.call();
     } finally {
       System.out.println(method + " took " + (System.currentTimeMillis() - start);
     }
   }
}

上面构建的代理可以安装在提供给任何 Java 代理的检测接口(interface)实例上。

与使用 Spring 相比,上述代理将适用于任何 Java 实例,而不仅仅是 Spring bean。

关于java - 执行方法栈中所有方法所花费的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29987725/

相关文章:

Java gRPC 客户端预测对 half_plus_two 示例模型的调用

java - jackson 单独使用字段名称对响应进行排序

java - 无法将字符串转换为正确的编码格式

linux - 测量时间 : differences among gettimeofday, TSC 和时钟滴答

arrays - 分析帮助 : slow matrix-scalar assignment

iphone - 在 iPad 上运行 Instruments 时遇到问题

java - CXF代码优先服务,WSDL生成; SOAP :address changes?

javascript - 在 JavaScript 中访问请求参数

java - 将 Spring 1.x 升级到 4.x

spring - 在 Java 中创建微服务的正确路径是什么? Spring Boot 或 OSGI