如何开始优化我的程序

时间:2011-08-31 12:23:02

标签: java optimization

我有一个用java编写的Web服务器程序,我的老板希望它运行得更快。

如果它没有错误地运行,我总是很高兴所以效率对我来说是新的。

我尝试了一个分析器,但它崩溃了我的电脑,结果证明是一个死的开源项目。

除了在这里阅读几个问题之外,我不知道我在做什么。我看到重新分解代码是最好的选择,但我不知道如何去做,我需要一个分析器来查看要重新考虑的代码。

所以有人知道我可以使用的免费分析器吗?我正在使用java和eclipse。如果可能的话,一些指令或类似的简单指令会很棒。

但是如果有人能给出它我真正想要的是这个主题的基本介绍,所以我可以理解足够深入研究这个主题以获得最佳结果。

在优化代码方面,我是一个完全的初学者,而且从我到目前为止所看到的主题看起来非常复杂,我们将非常感谢任何有关如何入门的帮助。

我是java的新手,所以说检查垃圾收集之类的东西对我来说没什么意义,id需要更详细的解释。

编辑:该程序使用tomcat进行联网。它连接到SQL数据库。 main函数是一个轮询循环,它检查网络上所有连接的设备,从中读取事件将事件写入数据库并执行事件功能。

我正在尝试改进轮询循环。该程序是多线程的,并且使用了大量的接口和代理,因此很可能看到代码越来越远离轮询循环。

我希望这些信息可以帮助您提供解决方案。我也没有构建它,我继承了代码。

9 个答案:

答案 0 :(得分:3)

首先检测瓶颈。如果方法运行500ms秒,那么在400ms运行5时,方法从100ms优化到VisualVM是没有意义的。

您可以尝试将JDK用作{{1}}中内置的分析器。

答案 1 :(得分:1)

如果您需要免费的分析器,请在Java附带时使用VisualVM。这可能已经足够了。

你应该向老板询问他想要更快的内容。没有必要优化他/她可能不关心的随机代码片段。 (很容易完成)

您还可以在任务/请求中记录关键点,以确定花费最多的时间。

答案 2 :(得分:1)

  编辑:该程序使用tomcat进行联网。它连接到一个   SQL数据库。主要功能是一个轮询循环,检查所有   在网络上连接的设备,从它们读取事件写入   事件到数据库并执行事件功能。

     

我正在尝试改进轮询循环。该计划很重要   多线程并使用大量的接口和代理,因此它很受欢迎   看看代码是否越来越远离轮询循环

这听起来像你有一个严重的I / O绑定应用程序。你真的没有太多可以做的,因为I / O绑定的应用程序使用CPU的效率不高 - 他们等待其他设备上的I / O操作完成。

FWIW,这个场景实际上是为什么许多大公司正在考虑转向廉价的基于ARM的解决方案。他们在强大的x86 CPU上浪费了大量的功能和资源,当他们的代码在那里等待远程MySQL或Oracle服务器完成其工作时,这些CPU得不到充分利用。有了这样的应用程序,为什么要投入比你需要的更多的CPU?

答案 3 :(得分:0)

如果你的java新手然后优化听起来像个坏主意。它很容易出错。在改变内部工作原理的同时重写代码并保持所有输出相同并非易事。

可能会查看您的存储过程,并将所有IN个参数替换为INNER JOIN。这是一种相当低风险和高回报的加速方式。

答案 4 :(得分:0)

    首先确定应用程序中各个步骤所花费的时间(使用日志记录来识别)。请注意是否有任何异常。
    进入上述每个步骤,看看是否存在任何瓶颈。确定是否可以缓存某些内容以保存数据库调用。通过将任务分解为独立单元来确定是否存在并行范围。

希望你有一些单元/集成测试,以确保你不会意外破坏任何东西。

答案 5 :(得分:0)

  1. 测量(使用分析器 - 正如其他人建议的那样,VisualVM很好)并找到程序花费大部分时间的位置。
  2. 分析热点并尝试改善其表现。
  3. 再次测量以验证您的更改是否具有预期效果。
  4. 如果需要,请从步骤1开始重复。

答案 6 :(得分:0)

开始很简单。

  • 从用户的角度列出一些缓慢的内容。
  • 尝试自己进行高级别的分析。也许是一个拦截器,可以为您的行为打印运行时间。
  • 然后仅使用Start time = System.currentTime...
  • 分析这些操作
  • 这种简单的方法可以成为更高级的分析的起点,如果幸运的话可以解决您的问题。

答案 7 :(得分:0)

在开始优化之前,您必须了解自己的工作负载,并且必须能够重新创建该工作负载。一种简单的方法是记录所有请求 in production ,其中包含足够的详细信息,您可以在开发环境中重新创建请求。

在记录负载的同时,您还可以记录这些请求的性能:从请求开始到结束的时间。一种方法(顺便提一下,捕获记录请求所需的数据)是在栈中添加一个servlet过滤器。

然后你可以开始来考虑优化。

  1. 建立绩效目标。简单地说“让它变得更快”毫无意义。相反,您需要建立目标,例如“只要少于100个并发用户,所有页面都应在1.5秒内响应。”
  2. 确定未达到效果目标的请求。首先关注最大的失败。
  3. 确定请求需要这么长时间的原因。
  4. 要做#3,您需要能够在开发环境中重新创建负载。然后,您可以使用分析器,或者只是将跟踪级别的日志记录添加到您的应用程序中,以了解该过程的每个步骤需要多长时间。


    还有整个优化领域,其中garbage collection tuning可能是最重要的。但同样,你需要建立并复制你的工作量,否则你就会岌岌可危。

答案 8 :(得分:0)

当开始优化应用程序时,主要风险是尝试优化每个步骤,这通常不会像预期的那样提高程序效率并导致无法维护的代码。

程序执行时间的80%可能是由单个步骤引起的,这个步骤本身只占代码库的20%。

要做的第一件事就是找出这个瓶颈。例如,您可以记录时间戳(使用System.nanoTime和/或System.currentTimeMillis以及您最喜欢的日志记录框架)来执行此操作。

确定步骤后,尝试编写运行此步骤的测试类,并使用分析器运行它。我对HPROF(http://java.sun.com/developer/technicalArticles/Programming/HPROF.html)都有很好的经验,虽然可能需要一些时间来熟悉,以及Eclipse测试和性能工具平台(http:/ /www.eclipse.org/tptp/)。如果您从未使用过探查器,我建议您从Eclipse TPTP开始。

执行配置文件将帮助您了解程序花费时间的方法。一旦你了解它们,查看源代码,并尝试理解它为什么慢。这可能是因为(这个清单并非详尽无遗):

  • 执行不必要的昂贵操作,
  • 使用次优算法,
  • 该算法生成大量对象,从而为垃圾收集器提供了大量工作(特别是对于具有中长期预期寿命的对象)。

如果代码中没有明显的缺陷,那么您可以考虑:

  • 使算法更加并行以便利用所有CPU
  • 购买更快的硬件。

关于JVM选项,性能最重要的两个选项是:

  • -server,为了使用服务器VM(默认情况下根据硬件启用),以较慢的启动价格提供更好的性能(http://stackoverflow.com/questions/198577/real-differences-之间-java的服务器和Java的客户机),
  • -Xms和-Xmx定义启动时可用的堆大小,以及JVM可以使用的最大内存量。如果JVM没有足够的内存,垃圾收集会占用大量CPU资源,从而减慢程序速度,但是如果JVM已经有足够的内存,增加堆大小不会提高性能,甚至可能导致更长的GC暂停。 (http://stackoverflow.com/questions/104381​​7/speed-tradeoff-of-javas-xms-and-xmx-options)

其他参数通常影响较小,您可以在http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html咨询。