`
alex8946
  • 浏览: 365475 次
  • 性别: Icon_minigender_1
  • 来自: 广东广州
社区版块
存档分类
最新评论

我的Java程序在做什么呢?

阅读更多

经常被客户问到这样的问题,我想知道我的Java应用到底在干什么?通常我会反问一句:你为什么想知道呢?得到的回答是,这个Java应用太耗用CPU的资源了,想知道它都耗在哪儿了!

我的这些客户其实都有一定的经验,他们知道怎样通过操作系统的工具和命令来查看某个应用对CPU的资源消耗。例如在Solaris中的prstat命令,就可以得到下面的输出

PID      USERNAME  SIZE     RSS     STATE  PRI   NICE      TIME    CPU    PROCESS/NLWP
 22227  root               706M  568M      cpu19    0        0          17:34:33  82%    appservDAS/89
  24348 root               570M  439M      sleep     59       0          0:00:05    0.7%    Xorg/15
   9053  root               215M  134M      sleep     1         0          5:55:37    0.5%    java/10
 18879  root               500M  386M      sleep    59       0           0:32:01    0.0%    Oracle/58
 24482  root               3384K 2936K     cpu0    49      0           0:00:00    0.0%    prstat/1
........
Total: 72 processes, 1483 lwps, load averages: 3.39, 3.40, 3.31

从上面的输出很容易判断哪个应用占用了多少CPU的资源。例如上面的例子JavaEE应用服务器“appservDAS”占用了82%的CPU资源。appservDAS的进程其实就是Java应用。那么要进一步判断这个进程为什么消耗了这么多的CPU呢?这不是件容易的事。我的客户先是获得了Java进程的一个快照,也叫ThreadDump。这很简单,只需要kill -3 22227就可以给这个Java进程一个信号,要求它打印出所有当前的线程调用栈。结果如下:

Full thread dump Java HotSpot(TM) Server VM (1.5.0_09-b03 mixed mode):

"RMI ConnectionExpiration-[10.1.4.206:43996,com.sun.appserv.management.client.AdminRMISSLClientSocketFactory@807653]" daemon prio=10 tid=0x028cb120 nid=0x24f6 waiting on condition [0xc30ff000..0xc30ffbf0]
 at java.lang.Thread.sleep(Native Method)
 at sun.rmi.transport.tcp.TCPChannel$Reaper.run(TCPChannel.java:446)
 at java.lang.Thread.run(Thread.java:595)

"RMI TCP Connection(4205)-10.1.4.206" daemon prio=10 tid=0x0110eb30 nid=0x24f4 runnable [0xc31ff000..0xc31ffaf0]
 at java.net.SocketInputStream.socketRead0(Native Method)
 at java.net.SocketInputStream.read(SocketInputStream.java:129)
 at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
 at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
 at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:723)
 - locked <0xf7362488> (a java.lang.Object)
 at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:680)
 at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
 - locked <0xf7362498> (a com.sun.net.ssl.internal.ssl.AppInputStream)
 at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
 at java.io.BufferedInputStream.read(BufferedInputStream.java:235)
 - locked <0xf325e540> (a java.io.BufferedInputStream)
 at java.io.FilterInputStream.read(FilterInputStream.java:66)
 at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:448)
 at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707)
 at java.lang.Thread.run(Thread.java:595)

"service-j2ee" daemon prio=10 tid=0x01c080d8 nid=0x811 runnable [0x00000000..0xc60ff7e0]

"service-j2ee" daemon prio=10 tid=0x01d78e60 nid=0x812 runnable [0x00000000..0xc541f7e0]

"service-j2ee" daemon prio=10 tid=0x010c98a0 nid=0x813 runnable [0x00000000..0xc53cf7e0]

"service-j2ee" daemon prio=10 tid=0x01d7b110 nid=0x814 runnable [0x00000000..0xc516f7e0]

.......

原谅我不把所有的长长的输出都写在这,总之很长,想想,有89个线程呢!从这里能看出什么来吗?能看出哪个线程花费了多少CPU吗?看不出来,因为快照是个静态的数据,只能知道当前每个线程在做什么,但是哪个线程花的CPU多就不得而知了。

通常要知道你的应用哪些部分花费的CPU资源多,需要profiling的工具(例如NetBeans的Profiler),但是这些工具使用和部署起来还是比较麻烦的,而且不适用于生产系统。下面提供一个简单的方法来快速的判断:

1 使用prstat的时候加上-L的参数,你就能获得每个操作系统的线程所消耗的资源。例如:

PID      USERNAME  SIZE     RSS     STATE  PRI   NICE      TIME    CPU    PROCESS/LWPID
 22227  root               706M  568M      cpu19    0        0          17:34:33  23%    appservDAS/89
22227  root               706M  568M      cpu19    0        0          17:34:33  12%    appservDAS/54
22227  root               706M  568M      cpu19    0        0          17:34:33  10%    appservDAS/31
22227  root               706M  568M      cpu19    0        0          17:34:33  10%    appservDAS/12
  24348 root               570M  439M      sleep     59       0          0:00:05    0.7%    Xorg/15
   9053  root               215M  134M      sleep     1         0          5:55:37    0.5%    java/10
 18879  root               500M  386M      sleep    59       0           0:32:01    0.0%    Oracle/58
 24482  root               3384K 2936K     cpu0    49      0           0:00:00    0.0%    prstat/1
........
Total: 72 processes, 1483 lwps, load averages: 3.39, 3.40, 3.31

这时候你能获得比刚才更详细的信息:哪个线程花费了多少CPU。但是这个线程号如何与Java Thread Dump文件中对应起来呢。很简单,在Java Thread Dump文件中,每个线程都有tid=...nid=...的属性,其中nid就是native thread id,也就是只的是LWPID号,只不过nid中用16进制来表示。例如上面的例子中,从prstat中,获得appservDAS的第89个线程消耗了很大的CPU,89的16进制是0x59,找到下面的线程:

"service-j2ee" daemon prio=10 tid=0x016158e8 nid=0x59 runnable [0xc789e000..0xc789f7e0]
 at com.sun.enterprise.web.connector.httpservice.HttpServiceConnector.jniRead(Native Method)
 at com.sun.enterprise.web.connector.httpservice.HttpServiceConnector.read(HttpServiceConnector.java:283)
 at com.sun.enterprise.web.connector.httpservice.HttpServiceRequestStream.read(HttpServiceRequestStream.java:55)
 at org.apache.jsp.mod_005fdms.commons.iWebServer_jsp$iWebSignature.ReadPackage(iWebServer_jsp.java:400)
 at org.apache.jsp.mod_005fdms.commons.iWebServer_jsp$iWebSignature.ExecuteRun(iWebServer_jsp.java:459)
 at org.apache.jsp.mod_005fdms.commons.iWebServer_jsp._jspService(iWebServer_jsp.java:672)
 at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:105)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:860)
....

就可以快速判断这个Java应用的资源消耗大概在什么地方了!

 

分享到:
评论

相关推荐

    java程序自动重新启动

    在给定的标题"java程序自动重新启动"中,我们可以理解这是一个实现了自动重启逻辑的Java程序。描述指出,这个程序由三个.java文件组成:Test.java、Watch.java和AbstractRun.java,它们构成了一个简单的自动重启系统...

    java程序做windows服务,随机启动

    在Windows操作系统中,Java程序...总之,将Java程序做成Windows服务,可以让程序在系统启动时自动运行,满足后台无人值守的需求。通过理解上述步骤和工具的使用,你可以有效地实现Java程序在Windows开机时随机启动。

    Java程序设计习题集下载

     趣味性:习题基本上覆盖了程序员在编写Java程序时经常出现的问题Java程序设计知识要点,各习题也列出其测试要点,从而方便教师从中挑选或改编考题以及方便学生进行实战模拟练习或测试,同时也可以为SCJP考试作准备...

    java程序坦克大战

    在java中如果我们需要用到图形界面,就得想到GUI(Graphic user interface),那么我们需要用到什么,就直接去查看API(图形化显示能让我们做完项目后将结果看得舒服,而不是全部都是代码) 要做GUI,就要想到java中...

    http客户端java程序

    http客户端java程序,代码质量高,经过测试。

    雍俊海 Java程序设计教程 课后答案

    在雍俊海的《Java程序设计教程》第二版的课后答案中,学生可以通过查看提供的代码,了解各种编程问题的解决方案,学习如何组织和优化代码,同时加深对Java语言特性和编程技巧的理解。通过实践,理论知识将更加牢固,...

    如何在 Web 浏览器中禁用 Java?

    在 Web 浏览器中,Java 插件允许用户运行 Java 应用程序和小程序。但是,Java 插件也可能带来安全隐患,例如恶意代码和恶意软件的攻击。 为了禁用 Java 在 Web 浏览器中的插件,我们可以使用 Java 控制面板。在 ...

    生日祝福java程序代码

    这个名为"生日祝福java程序代码"的压缩包显然包含了多个功能模块,旨在为生日庆祝活动增添乐趣。以下是该程序可能包含的关键知识点和组件的详细说明: 1. **Java编程基础**:首先,整个项目基于Java语言编写,这...

    java 求爱 小程序

    它的“一次编写,到处运行”(Write Once, Run Anywhere)特性使得Java程序可以在任何安装了Java虚拟机(JVM)的设备上运行,这包括个人电脑、移动设备甚至服务器。 在【LoveForEver.java】文件中,我们可以看到...

    Java 程序设计与项目实践

    在Java程序设计方面,这本书会覆盖以下关键知识点: 1. **Java基础知识**:包括Java语法基础,如变量、数据类型、运算符、流程控制语句(如if、switch、for、while)、类与对象、封装、继承和多态等面向对象概念。 ...

    Java程序设计考试试卷和答案(共4套)

    Java程序设计笔试试卷和答案(共2套): 《Java程序设计》笔试卷A.doc ; 《Java程序设计》笔试卷A答案.doc ; 《Java程序设计》笔试卷B.doc ; 《Java程序设计》笔试卷B答案.doc Java程序设计上机考试试卷和答案...

    一些比较有意思的Java小程序

    1. **猜数字游戏**:这是许多初学者都会接触到的经典Java程序。通过随机生成一个数字,让玩家猜测,然后提供反馈(过高、过低或正确),直到猜对为止。这个程序可以帮助学习者理解基本的输入输出、条件判断和循环...

    JAVA语言程序设计(郎波主编)例题

    =、&gt;、&lt;、&gt;=、)的例题,这些基础知识是编写任何JAVA程序的基础。 控制流程是程序设计的关键部分,包括条件语句(if-else、switch)和循环结构(for、while、do-while)。通过解决书中关于这些话题的例题,学习者能...

    java程序设计教程第七版课后习题答案

    Java程序设计教程第七版是Java学习者的重要参考资料,其课后习题答案对于巩固理论知识、提高编程技能具有极大帮助。本教程涵盖了Java语言的基础到高级特性,包括但不限于语法、面向对象编程、异常处理、集合框架、多...

    java分布式程序设计

    java分布式程序设计 java分布式程序设计 java分布式程序设计java分布式程序设计java分布式程序设计java分布式程序设计java分布式程序设计java分布式程序设计java分布式程序设计java分布式程序设计

    Java B/S 抽奖程序

    总的来说,Java B/S 抽奖程序是一个结合了前端交互设计和后端逻辑处理的综合性项目,它展示了Java在Web开发领域的强大能力。无论是对于初学者还是经验丰富的开发者,这样的程序都提供了学习和实践的绝佳机会。通过对...

    Java Web程序设计教程.pdf

    标题《Java Web程序设计教程》与描述《Java Web程序设计教程 Java Web程序设计教程》中的知识点主要涵盖了Java Web应用开发领域的核心技术与实践。本书作为21世纪高等学校计算机规划教材,由范立锋与林果园共同编著...

    自考java 04747《Java语言程序设计(一)》教材电子版

    《Java语言程序设计(一)》是自考Java专业的一门重要课程,旨在帮助学习者掌握Java编程的基础知识和技能。这门课程涵盖了Java语言的基本语法、数据类型、控制结构、类与对象、异常处理、输入输出以及简单的多线程...

    Java应用程序运行工具1.0

    1. **自动查找JRE**:工具会自动检测系统中的Java运行时环境,使得即使在没有预设环境变量的情况下也能正常运行Java程序。 2. **智能管理类路径**:用户可以通过配置文件或默认设置告知startJava需要加载的类路径,...

    java程序设计实用教程第三版

    《Java程序设计实用教程第三版》是一本专为初学者和有一定基础的程序员设计的Java学习教材。本书全面覆盖了Java编程的基础知识,包括语法、类与对象、接口与继承、异常处理、多线程、网络编程、数据库操作等多个方面...

Global site tag (gtag.js) - Google Analytics