2010-08-24 74 views
2

我们有一个Java ERP类型的应用程序。服务器和客户端之间的通信通过RMI进行。在高峰时段,最多可以有250个用户登录,其中约20个用户正在同时工作。这意味着在高峰时段的任何时间都有大约20个线程在线。 服务器可以运行数小时而没有任何问题,但突然间的响应时间会越来越快。响应时间可以在几分钟内完成。如何确定为什么Java应用程序很慢

我们使用Sun的JDK 1.6.0_16在Windows 2008 R2上运行。我们一直在使用perfmon和Process Explorer来查看正在发生的事情。唯一让我们觉得奇怪的是,当服务器开始工作时,java.exe进程打开的句柄数量大约为3500.我并不是说这是一个问题。

我只是好奇,如果有一些指导原则,我应该按照指出问题。我应该使用哪些工具? ....

+0

什么是内存使用情况 - 真实还是虚拟 - 当你出现放缓时会怎么做? – 2010-08-24 17:32:41

回答

1

听起来像垃圾收集不能跟上,并开始“停止世界”收集由于某种原因。

在启动时附加JDK中的jvisualvm,并在性能下降时查看收集的数据。

+0

我在今天的启动脚本中添加了-verbose:gc。如果GC是问题,我会明天再见。 – kovica 2010-08-24 16:24:56

+0

你发现了什么? – 2011-11-10 21:57:15

4

您可以访问此应用程序的日志配置吗?

如果可以,应该将日志级别更改为“DEBUG”。跟踪请求的调试日志可以为您提供有关争用点的有用信息。

如果不能,分析器工具可以帮助您:

  • VisualVM(免费,以及良好的产品)
  • Eclipse TPTP(免费,但比VisualVM的更复杂)
  • JProbe(不免费但功能强大,它是我最喜欢的Java分析器,但价格昂贵)

如果应用程序已经用JMX控制poi nts,你可以插入一个JMX查看器来获取信息...

如果你想强调应用程序触发问题(如果你想验证它是否是一个收费问题),你可以使用压力工具,如JMeter

+0

可悲的是我们没有使用log4j或任何日志框架。服务器现在大约有10年历史了,要改变它会很昂贵。 如果缓慢会在测试系统上显示出来,那么使用profiler会很好。由于这是一个生产系统,我无法在那里玩。 JMeter不支持通过RMI进行测试。 – kovica 2010-08-24 16:28:14

0

你所描述的问题很典型,但也很普遍。原因可能从内存泄漏,资源争用等等到糟糕的GC策略以及堆/ PermGen空间分配。为了指出应用程序的确切问题,您需要对其进行概要分析(我知道诸如Yourkit和JProfiler之类的工具)。如果你明智地分析你的应用程序,只有一些应用程序周期会揭示问题,否则分析本身不是很容易。

0

在类似的情况下,我自己编写了一个简单的剖析代码。基本上我使用了一个ThreadLocal,其中有一个“StopWatch”(基于LinkedHashMap),然后我将如下代码插入到应用程序的各个点中:watch.time("OperationX");

然后在线程完成任务后,请拨打电话watch.logTime();,该班会写下如下所示的日志:[DEBUG] StopWatch time:Stuff=0, AnotherEvent=102, OperationX=150

之后,我编写了一个简单的解析器,可以从此日志(每个代码路径)生成CSV。你可以做的最好的事情是创建一个直方图(可以使用Excel轻松完成)。平均值,中等和偶数模式都可以欺骗你。我强烈建议创建一个直方图。

与此直方图一起,您可以使用平均/中等/模式(它代表最佳数据,您可以从直方图中确定此数据)创建线图。

通过这种方式,您可以百分之百地确切地知道什么操作需要花费时间。如果你不能确定罪魁祸首,二进制搜索是你的朋友(罚款事件)。

可能听起来真的很原始,但起作用。另外,如果您从中创建一个库,则可以在任何项目中使用它。这也很酷,因为你可以很容易地在生产中打开它。

0

除了其他人提到的GC以外,尝试在减速过程中每隔5-10秒尝试一次线程转储,持续约30秒。可能会出现数据库调用,Web服务或其他依赖项变慢的情况。如果您仔细观察胎面垃圾箱,您将能够看到看起来不会移动的线,并且您可以通过这种方式缩小罪魁祸首。

从GC的角度来看,您是否在这些时间监控您的CPU使用情况?如果GC频繁运行,您将看到整体CPU使用率的跳跃。

如果只有这是一个Solaris盒子,prstat会是你的朋友。

0

对于像这样的急性问题,快速jstack <pid>应该快速指出问题区域。可能不需要让所有人都喜欢它。

如果我不得不猜测,我会说热点跳进来,并严格优化了一些写得不好的代码。 Netbeans开始停止使用新创建的对象来缓存文件数据的地方WeakHashMap。经过优化后,可以在添加后直接从地图中删除条目。很明显,如果缓存被依赖,那么很多文件活动就是如此。您可能不会看到驱动器亮起,因为它将全部由操作系统缓存。