任何推荐的Java分析教程?
有没有推荐的Java应用程序分析教程?
我现在使用JProfiler和Eclipse testing和性能工具平台 (TPTP)与我的分析。 但是,虽然装备了精彩的武器,但作为一个新来的Java新人,我仍然缺less找出瓶颈的一般理论和技巧。
分析是一门学科不止一个学科。
更受欢迎的是你继续进行测量 。 也就是说,你试着看看每个函数需要多长时间和/或多less次调用。 显然,如果一个函数花费很less的时间,那么加速它将会使你获得很less的收益。 但是,如果花费很多时间,那么你就必须做一些侦察工作来弄清楚函数的哪一部分是时间的负责。 不要指望函数时间和总时间相加,因为函数互相调用,而函数A可能花费很多时间的原因是它调用函数B也花费很多时间。
这种方法可能会发现很多问题,但是这取决于你是一个好的侦探,并且能够清楚地考虑不同types的时间,如挂钟时间与CPU时间,自我时间与包容时间。 例如,应用程序可能看起来很慢,但function时间可能全部报告为接近于零。 这可能是由程序被I / O限制引起的。 如果I / O是你期望的东西,那可能是好的,但它可能正在做一些你不知道的I / O,然后你又回到了侦探工作。
对性能testing人员的一般期望是,如果你能够修复足够的东西来获得10%或20%的加速,这是相当不错的,而我从来没有听说过重复使用profiler的故事来获得更多的加速。
另一种方法是不去衡量,而是去捕捉 。 这是基于这样一个想法,即在程序花费的时间比在你想要的时间更长的时候,你想知道它在做什么,主要是知道它在做什么,并且找出一个办法就是阻止它并且询问,或者对其状态进行快照,并对其进行分析,以便完全理解它在做什么以及为什么在特定的时间点这样做。 如果您多次执行此操作,并且看到多次尝试执行的操作,那么您可以对此进行有效的优化。 不同的是,你不是问多less ; 你在问什么和为什么 。 这是另一个解释。 (请注意,拍摄这样的快照并不重要,因为你不是在问时间,而是在问这个程序在做什么,为什么。)
在Java的情况下, 这是一个低技术,但高效的方法来做到这一点,或者你可以使用Eclipse中的“暂停”button。 另一种方法是使用特定types的分析器,一个是对整个调用堆栈进行采样,在挂钟时间(不是CPU,除非您希望盲目I / O),当您想要采样时(例如,不当等待用户input时),并且在代码行的级别上进行总结,不仅在function级别上,而且在时间百分比上,而不是绝对时间上。 为了获得时间百分比,它应该告诉你,对于每一个样本上出现的每行代码,包含该行的样本的百分比,因为如果你可以使这条线消失,你会节省这个百分比。 (你应该忽略其它的事情,比如调用图表,recursion和自定义)。很less有符合这个规范的profilers,但是一个是RotateRight / Zoom ,但是我不确定它是否适用于Java,可能还有其他的。
在某些情况下,可能很难在需要的时候获取堆栈样本,在实际的缓慢时间内。 那么,因为你所追求的是百分比,你可以对代码做任何事情,这样就可以在不改变百分比的情况下更容易地获取样本。 其中一种方法是通过包装一个临时循环来放大代码,例如100次迭代。 另一种方法是在debugging器下设置数据更改断点。 这将导致代码被解释比正常慢10到100倍。 另一种方法是使用一个闹钟定时器在缓慢的时间内closures,并用它来抓取一个样本。
使用捕获技术,如果您反复使用它来查找并执行多次优化,则可以期望达到接近最佳的性能。 在大型软件的情况下,瓶颈更多,这可能意味着很多因素。 堆栈溢出的人报告了从7倍到60倍的因素。 这里是一个43x的详细例子。
捕获技术遇到困难的情况下,很难弄清楚为什么线程正在等待,比如等待事务在另一个处理器上完成。 (测量有同样的问题。)在这些情况下,我使用合并时间戳日志的费力的方法。
我正在使用Yourkit Java Profiler 11.0,它非常好,为了内存优化和监视CPU时间。 此外,yourkit网站有一个良好的知识库和帮助主题。
作为分析的新手,您应该从寻找运行时间长的方法开始,或者在典型的使用模式/瓶颈出现的地方多次调用。
我不确定Eclipse JProfiler是如何工作的,因为我主要使用NetBeans 。 但是,在NetBeans中,有一个“快照”视图,显示了运行时方法调用的层次结构,总和达到100%。 我查找了占用总时间(相对)很大一部分的层次结构部分。 从那里你必须考虑这些方法在做什么,以及什么可能导致它们变慢。
例如:我注意到一个被频繁调用的方法总体上花费了太多时间来完成,而且是一个严重的瓶颈。 长话短说,事实certificate代码正在使用.contains()
方法检查一个项目是否存在于一个集合中,并且该集合是一个链接列表。 这是一个问题的原因是因为链接列表的O(n)像.contains()
函数的时间复杂性。 这种情况下的修复非常简单,因为我可以用一个哈希集replace链表,它在O(1)时间内执行.contains()
快得多。
JProfiler附带它的帮助手册。 我发现这很好。
您可能会发现Java平台性能感兴趣的书。 由Sun Microsystems发布。