2

我们有一个 Java ERP 类型的应用程序。服务器和客户端之间的通信是通过 RMI 进行的。在高峰时段,最多可以有 250 名用户登录,其中大约 20 人同时工作。这意味着在高峰时段的任何给定时间大约有 20 个线程处于活动状态。服务器可以运行几个小时而没有任何问题,但是突然之间响应时间变得越来越长。响应时间可以在几分钟内。

我们在带有 Sun 的 JDK 1.6.0_16 的 Windows 2008 R2 上运行。我们一直在使用 perfmon 和 Process Explorer 来查看发生了什么。我们唯一觉得奇怪的是,当服务器开始运行缓慢时,java.exe 进程打开的句柄数约为 3500。我并不是说这是实际问题。

我只是好奇是否有一些我应该遵循的指导方针以便能够查明问题。我应该使用什么工具?……

4

6 回答 6

3

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

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

如果你不能,探查器工具可以帮助你:

  • VisualVM(免费,好产品)
  • Eclipse TPTP(免费,但比 VisualVM 更复杂)
  • JProbe(不是免费但非常强大。它是我最喜欢的 Java 分析器,但它很贵)

如果应用程序是使用 JMX 控制点开发的,您可以插入 JMX 查看器以获取信息...

如果要对应用程序进行压力触发问题(如果要验证是否是充电问题),可以使用JMeter之类的压力工具

于 2010-08-24T16:09:52.550 回答
1

听起来垃圾收集无法跟上并出于某种原因开始“停止世界”收集。

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

于 2010-08-24T16:08:44.533 回答
0

对于像这样的严重问题,快速jstack <pid>应该快速指出问题区域。可能没有必要全神贯注。

如果我不得不猜测,我会说 Hotspot 加入并严格优化了一些写得很糟糕的代码。Netbeans 停止使用WeakHashMap新创建的对象来缓存文件数据。优化后,条目可以在添加后直接从地图中删除。显然,如果依赖于缓存,则会出现大量文件活动。您可能不会看到驱动器亮起,因为它都会被操作系统缓存。

于 2010-08-24T17:27:32.410 回答
0

除了其他人提到的 GC 之外,在减速期间尝试每 5-10 秒进行一次线程转储约 30 秒。可能存在 DB 调用、Web 服务或其他一些依赖项变慢的情况。如果您查看胎面转储,您将能够看到似乎没有移动的螺纹,并且您可以通过这种方式缩小您的罪魁祸首。

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

如果这是一个 Solaris 机器,prstat 将是您的朋友。

于 2010-08-24T16:50:48.403 回答
0

您描述的问题很典型,但也很普遍。原因可能从内存泄漏、资源争用等到错误的 GC 策略和堆/永久代空间分配。要指出您的应用程序的确切问题,您需要对其进行分析(我知道像 Yourkit 和 JProfiler 这样的工具)。如果您明智地分析您的应用程序,那么只有一些应用程序周期会揭示问题,否则分析本身并不是很容易。

于 2010-08-24T16:25:28.210 回答
0

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

然后在线程完成任务后,我会调用watch.logTime();并且该类将编写一个如下所示的日志:[DEBUG] StopWatch time:Stuff=0, AnotherEvent=102, OperationX=150

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

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

通过这种方式,您可以 100% 确定确切的操作需要时间。如果您无法确定罪魁祸首,二分搜索就是您的朋友(细粒度的事件)。

可能听起来很原始,但有效。此外,如果你用它制作一个库,你可以在任何项目中使用它。它也很酷,因为您也可以在生产中轻松打开它。

于 2010-08-24T16:32:27.623 回答