Springframework的InvocableHandlerMethod.getMethodArgumentValues吃了很多cpu

时间:2014-07-30 15:42:59

标签: spring

我有一个使用Spring 4.0编写的Java应用程序,并部署在tomcat上(在red hat linux上)。在使用JProfiler分析我们的webapp时,我们发现大部分时间都花在Springframework中,这导致我们的API速度减慢。例如考虑下面提到的数据,这些数据显示在614秒内,在Spring内部花费了609秒,这是针对105个API调用,这意味着每个API调用时间约为6秒。 所以我想知道春天是否有配置可以避免这种开销?

编辑:使用JProfiler

添加更多数据
  91.0% - 614 s org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest 
        90.2% - 609 s org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues
            55.9% - 377 s org.springframework.validation.DataBinder.convertIfNecessary
            34.2% - 231 s org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName
        0.8% - 5,709 ms org.springframework.web.method.support.InvocableHandlerMethod.invoke

修改 在进一步向下钻探时,我发现在这90.2%中,88%的时间被以下2种方法吃掉

  org.springframework.util.ConcurrentReferenceHashMap.put
  org.springframework.util.ConcurrentReferenceHashMap.get

他们正在被召唤     org.springframework.core.ResolvableType.forType

有没有人在使用Spring应用程序的linux上观察过这个?

FYI我的Controller方法有23个查询参数,其中9个是List<>,这会产生任何问题吗?我不应该有这么多的查询参数(@RequestParam)吗?

2 个答案:

答案 0 :(得分:1)

park没有执行繁忙的等待。它实际上甚至不知道线程正在等待的条件。这取决于来电者。但是,如果经常调用park,则仍会占用大量CPU,例如:已调用unpark但在重新检查后再次调用等待条件park。然后park的固定开销将累积。

所以你在这里的情况似乎是你对特定的锁有很大的争用。从您发布的堆栈跟踪中我猜测ConcurrentReferenceHashMap已经配置为并发级别远远小于您的实际线程数。

答案 1 :(得分:0)

似乎是一个自定义参数解析器就行了。在

中创建一个之后

Spring HandlerMethodArgumentResolver not executing
jprofiler时间很好,我的customArgumentResolver没有吃掉与HandlerMethodArgumentResolverComposite.resolveArgument一样多的CPU 正在做。

现在额外90.2%的时间减少到2%(10秒)