跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

这是您第一次登陆到 developerWorks,已经自动为您创建了您的概要文件。 选择您概要文件中可以公开的信息的信息(如姓名、国家/地区,以及公司),这些信息同时也会与您所发布的内容相关联。 您可以随时更新您的 IBM 账号。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

通过 Health Center API 监视 Java 应用程序,第 1 部分

Health Center API 入门

Toby Corbin, 软件工程师, IBM
Photo of TobyCorbin
Toby Corbin 是 IBM Java 技术中心的一名软件工程师,目前正在开发 RAS 工具。他于 2001 加入 IBM,四年的时间里一直在开发 Java Runtime Environment 的国际语言支持和全球化,之后的两年从事 Swing 和 AWT 库的开发。

简介: Health Center 2.1 版包含一个功能强大的 API。该 API 允许 Java™ 开发人员将 Health Center 嵌入到其应用程序中,还允许利用其监视功能来解决问题。本文章系列由两个部分组成,在本系列的第 1 部分中,您将学习如何使用 Health Center API,以及如何监视正在运行的 Java 应用程序中的死锁。第 2 部分 使用了本文中开发的死锁检测应用程序,并添加了一个方法分析视图来显示应用程序的哪些地方花费了大部分的 CPU 周期。

发布日期: 2013 年 6 月 06 日
级别: 初级 原创语言: 英文
访问情况 : 5715 次浏览
评论: 


您是否曾经遇到过没有明确原因的应用程序服务器挂起或者 Java 应用程序变得没有响应?您的应用程序是否内存不足或者运行情况欠佳?使用 Health Center,您就可以更轻松地解决这些问题。

使用 Health Center 监视和诊断问题

Health Center 是一款适用于 Java 的 IBM® 监视和诊断工具,是一个免费的低开销诊断工具和 API,用于监视在 IBM Java 虚拟机 (JVM) 上运行的应用程序。借助 Health Center,您可以通过提供信息来快速评估正在运行的 Java 应用程序的状态,从而确定问题并帮助解决问题。您可以:

  • 确定是否存在本机或堆内存泄露
  • 发现哪些方法需要使用较长的运行时间
  • 确定 I/O 瓶颈
  • 使垃圾收集可视化并进行调优
  • 查看所有锁争用
  • 分析异常的 WebSphere® Real Time 事件
  • 监视应用程序的线程活动
  • 检测死锁条件
  • 收集类的直方图数据

最新版本的 Health Center 是一个功能强大的全新 API,您可以使用它编写自己的监视工具。令人烦恼的难于查找问题的时代马上就要结束了。

在本文中,我们将学习编写一个用于检查应用程序死锁条件的监视工具,然后,应用这些原则来编写更深入的工具、查询从垃圾收集活动到方法分析的所有问题,并确定应用程序将其 CPU 周期花费在了哪些地方。

系统要求

Health Center API 包至少需要安装 Eclipse 3.4 或 Eclipse 4.x。

将 API 程序包安装到 Eclipse 中

IBM 监视和诊断工具通常安装在 IBM 支持助手 (ISA) 中,要将 Health Center 嵌入您的应用程序并使用 API 对其进行编码,首先需要将它安装到您的 Eclipse 环境中。为此,请执行以下步骤:

  1. 启动 Eclipse 开发环境。
  2. 转到 Help -> Install New Software
  3. 添加 ISA 更新网站作为一个新网站。
    1. 单击 Add
    2. 在名称框中输入 ISA Update 网站。
    3. 在位置框中输入此 URL:http://public.dhe.ibm.com/software/isa/isa410/production/。该操作会启动对所有可用工具的搜索,该搜索可能需要花费几分钟的时间。
  4. 在搜索框中输入 Health Center
  5. 选择程序包 Health Center Core Feature 并单击 Next(参见图 1):

    图 1. 将要安装的可用软件的列表
    将要安装的可用软件的屏幕截图

  6. 确认安装细节并单击 Next
  7. 阅读并接受许可条款,然后单击 Finish。这些步骤会将 Health Center 核心功能安装到您的 Eclipse IDE 中。您可以准备好对此 API 进行编码。
  8. 确认安装细节并单击 Next

使用此 API 编写一个简单的 rcp 来检测死锁。首先,在 Eclipse 中创建一个新的插件项目并添加 Health Center API 作为一个依赖项。为此,请执行以下步骤:

  1. 转到 File -> New -> Project -> Plug-in Project
  2. 为该项目提供一个名称,如 HC_Deadlock。单击 Next
  3. 清除 Generate an activator 复选框。当系统询问您是否想创建一个富客户端应用程序时,单击 Yes。然后单击 Next(参见图 2):

    图 2. 插件项目选项
    插件项目选项的屏幕截图

  4. 单击 Next。在模板屏幕上,选择 Headless Hello RCP。然后单击 Finish

接下来,将 Health Center API 程序包作为依赖项添加到这个新项目。请遵循以下步骤:

  1. 要将 API 导入添加到清单中,请打开新项目中 META-INF 下的 MANIFEST.MF 文件(参见图 3):

    图 3. Package Explorer 插件
    Package Explorer 插件的屏幕截图

  2. 选择 Dependencies 选项卡并单击 Add。在 Select a Plug-in 字段的搜索中键入 healthcenter.api。选择 com.ibm.java.diagnostics.healthcenter.api 插件,请注意,版本号可能有所不同(参见图 4):

    图 4. Health Center API 插件选择
    Health Center API 插件选择的屏幕截图

  3. 单击 OK。重复 选择 Dependencies 选项卡 步骤中的练习。这次,再次添加 org.eclipse.ui,版本号可能会有所不同(参见图 5):

    图 5. org.eclipse.ui 的插件选择
    org.eclipse.ui 的插件选择的屏幕截图

  4. 单击 OK,然后保存该文件。

此 API 插件现在已经包含在您的应用程序中,您可以开始对其进行编码了。


测试死锁应用程序

编写死锁监视工具之前,您可能想监视某些内容。清单 1 显示了一个获取死锁的简单应用程序的源代码:


清单 1. 一个具有死锁的简单应用程序
				
public class GenerateDeadlock {
   AThread t1 = null;
   AThread t2 = null;
   AThread t3 = null;

   static class AThread extends Thread {
      Object hold;
      Object grab;

      AThread(String name, Object hold, Object grab) {
         super(name);
         this.hold = hold;
         this.grab = grab;
      }

      private void delay(long time) {
         try {
            Thread.sleep(time);
         } catch (InterruptedException e) {
         }
      }

      private void grabLocks() {
         System.out.println("Thread " + this + " about to hold " + hold);
         synchronized (hold) {
            System.out.println("  Thread " + this + " about to grab "
                  + grab);
            delay(5000);
            synchronized (grab) {
               System.out.println("    Thread " + this
                     + " got both monitors");
               delay(1000000);
            }
         }
      }

      public void run() {
         System.out.println("Thread " + this + " starting");
         for (int i = 0; i < 200000; i++) {
            grabLocks();
         }
         System.out.println("Thread " + this + " completed");
      }
   }

   private void createDeadlock() {
      System.out.println("Force 3 thread deadlock");
      String s1 = "obj 1";
      String s2 = "obj 2";
      String s3 = "obj 3";
      t1 = new AThread("Thread 1", s1, s2);
      t2 = new AThread("Thread 2", s2, s3);
      t3 = new AThread("Thread 3", s3, s1);
      t1.start();
      t2.start();
      t3.start();
   }

   public static void main(String[] args) {
      GenerateDeadlock d = new GenerateDeadlock();
      d.createDeadlock();
      try {
         Thread.sleep(1000);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      System.out.println("Press a key to exit");
      try {
         System.in.read();
         System.exit(0);
      } catch (java.io.IOException e) {
      }
   }
}


Health Center 包含两个部分,第一部分是 Health Center 代理,它与要监视的应用程序一起加载。该代理提供了对 JVM 中数据的访问,这就是随后要使用的 Health Center 的第二部分,即客户端。此 API 为您提供了访问客户端的访问权限,通常是从 ISA 开始。将此客户端嵌入您的应用程序中,以便连接到使用 Health Center 代理启动的应用程序,并获得访问 Health Center 客户端监视和显示的所有数据的权限。此 API 不提供 GUI,而是生成可在您自己的应用程序中使用的所有数据。图 6 概述了将 Health Center 客户端和代理安装到 ISA 和 JVM 中时它们所在的位置:


图 6. Health Center 客户端和代理安装在 ISA 和 JVM 中时所在的位置
ISA 和 JVM 中的 Health Center 客户端和代理的位置图

启动 清单 1 中的程序及其连接的 Health Center 代理。它至少需要 IBM Java 级别的 Java 5 SR8、Java 6 SR1 或 Java 7。您可以下载 IBM 开发人员工具包

要使用 Java 5 SR10 及其更高版本、Java 6 SR5 及更高版本和 Java 7 来启动应用程序与代理,请使用以下命令(参见图 7):

java - Xhealthcenter GenerateDeadlock

对于 Java 5 SR9 及其早期版本或者 Java 6 SR4 及其早期版本,请使用以下命令:

java - agentlib:healthcenter - Xtrace:output=healthcenter.out GenerateDeadlock


图 7. 运行 GenerateDeadlock 程序
显示了 GenerateDeadlock 程序的命令行窗口的屏幕截图

Java 5 SR9 和 Java 6 SR3 自动包含此代理。有关最新版本的代理以及如何更新代理的说明,请访问 Health Center - 安装 Health Center 代理


编写死锁监视应用程序代码

现在,您可以使用 Health Center API 修改基本的 Hello RCP World 应用程序,并将其转变成死锁检测工具。打开名为 Application.java 的文件(参见图 8):


图 8. Application.java 代码的位置
Application.java 代码位置的屏幕截图

设置连接详细信息

首先,获取一个 ConnectionProperties 对象,该对象包含您要连接的应用程序的详细信息。默认的对象设置为使用 localhost 和端口 1972,但您可以在构造函数和类方法中更改这些值(和提高安全性):

ConnectionProperties hcConn = new ConnectionProperties();

在拥有 ConnectionProperties 对象时,可以连接到您要监视的应用程序,该应用程序已经与 Health Center 代理一起启动。调用静态的 HealthCenterFactory.connect(hcConn, true) 方法。该调用返回一个 HealthCenter 对象,此对象直接连接到 Health Center 并且允许访问 Health Center 监视的所有数据。此连接调用有效地启动了您的应用程序中的一个 Health Center 实例并开始收集数据:

HealthCenter hcMon = HealthCenterFactory.connect(hcConn,true);

获取数据

在拥有 HealthCenter 对象之后,就可以开始查询数据。采用类似于 GUI的方式布置此 API:在获取 HealthCenter 对象之后,此 API 的第一步操作就是调用您感兴趣的数据类型。对于此示例,我们希望检查死锁,它是 ThreadsData 类的一部分。您可以在 HealthCenter 对象上使用 getThreadsData() 方法进行访问,如下所示:

ThreadsData hcThreadsData = HealthCenter.getThreadsData();

ThreadsData 类包含一个 deadlockDetected() 方法,该方法在检测到死锁时返回 true。通过轮询该方法,就可以知道是否发生了死锁:

if(hcThreadsData.deadlockDetected()) {
      do something
}

访问建议和分析引擎

Health Center 有一个内置的建议引擎,该引擎提供所有分析并返回结果。通常,在运行完整版的 Health Center 时,通常会在 Analysis and Recommendations 面板中看到这些结果(参见图 9):


图 9. Health Center 中的 Analysis and Recommendations 面板
Health Center 的 Analysis and Recommendations 面板的屏幕截图

要查询任何建议,可采用一些方法。getAllRecommendations() 返回所有建议的数组,但您可以只使用 getCriticalRecommendations() 调用来查询关键问题,该调用是将在 ThreadsData 对象上使用的一个调用:

String[] hcThreadsRec = hcThreadsData.getCriticalRecommendations()

查看完整的源代码

前五个调用是在应用程序中嵌入 Health Center 以及在要监视的应用程序中检查死锁所必需的。清单 2 显示了包含所用调用的完整源代码:


清单 2. 显示了所使用的五个调用的完整源代码
				
package deadlockdemo;

import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;

import com.ibm.java.diagnostics.healthcenter.api.ConnectionProperties;
import com.ibm.java.diagnostics.healthcenter.api.HealthCenter;
import com.ibm.java.diagnostics.healthcenter.api.factory.HealthCenterFactory;
import com.ibm.java.diagnostics.healthcenter.api.threads.ThreadsData;

/**
 * This class controls all aspects of the application's execution
 */
public class Application implements IApplication {
   HealthCenter hcMon;

   public Object start(IApplicationContext context) throws Exception {
      ConnectionProperties hcConn = new ConnectionProperties();
      hcMon = HealthCenterFactory.connect(hcConn, true);
      try {
         System.out
               .println("Waiting for 10 seconds to allow initial data to be
                        parsed from the connection");
         Thread.sleep(10000);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      checkForDeadlock();
      return IApplication.EXIT_OK;
   }

   public void stop() {
      // nothing to do
   }

   public void checkForDeadlock() {
      while (!detectDeadlock()) {
         try {
            Thread.sleep(5000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }

   private boolean detectDeadlock() {
      ThreadsData hcthreadsData = hcMon.getThreadsData();
      if (hcthreadsData == null) {
         System.out.println("No threads yet");
      } else {
         if (hcthreadsData.deadlockDetected()) {
            Display display = new Display();
            Shell shell = new Shell(display);

            MessageBox mb = new MessageBox(shell);
            String deadlockMessage = new String();
            String[] hcThreadsRec = hcthreadsData
                  .getCriticalRecommendations();
            for (String rec : hcThreadsRec) {
               deadlockMessage = deadlockMessage + rec + "\n";
            }
            mb.setMessage(deadlockMessage);
            mb.setText("Deadlock detected");
            mb.open();
            display.dispose();
            return true;
         }
      }
      return false;
   }
}


监视死锁

现在,您已经在后台运行死锁监视应用程序和有死锁缺陷的程序。一些消息指示了存在死锁(参见图 10):


图 10. 死锁检测结果面板
死锁检测结果面板的屏幕截图

结束语

本文介绍了如何开始使用 Health Center API 的基础知识,然后介绍了如何编写一个用于检查应用程序死锁条件的监视工具。您可以应用这些技术来提取和使用 Health Center 中的任何数据。在 第 2 部分 中,将会在这些概念上进行操作,并在死锁检测应用程序中添加一个方法分析视图,以显示应用程序中花费最多 CPU 周期的地方。


参考资料

学习

获得产品和技术

讨论

  • Health Center 论坛:参与与 Health Center 相关的讨论。

  • 加入 developerWorks 社区:探索由开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户进行交流。

关于作者

Photo of TobyCorbin

Toby Corbin 是 IBM Java 技术中心的一名软件工程师,目前正在开发 RAS 工具。他于 2001 加入 IBM,四年的时间里一直在开发 Java Runtime Environment 的国际语言支持和全球化,之后的两年从事 Swing 和 AWT 库的开发。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology
ArticleID=932811
ArticleTitle=通过 Health Center API 监视 Java 应用程序,第 1 部分
publish-date=06062013