﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-szhswl-文章分类-开发测试工具</title><link>http://www.blogjava.net/szhswl/category/27805.html</link><description>宋针还的个人空间</description><language>zh-cn</language><lastBuildDate>Mon, 07 Jan 2008 05:21:45 GMT</lastBuildDate><pubDate>Mon, 07 Jan 2008 05:21:45 GMT</pubDate><ttl>60</ttl><item><title>利用JProfiler对应用服务器内存泄漏问题诊断一例(转载)</title><link>http://www.blogjava.net/szhswl/articles/173288.html</link><dc:creator>宋针还</dc:creator><author>宋针还</author><pubDate>Mon, 07 Jan 2008 04:03:00 GMT</pubDate><guid>http://www.blogjava.net/szhswl/articles/173288.html</guid><wfw:comment>http://www.blogjava.net/szhswl/comments/173288.html</wfw:comment><comments>http://www.blogjava.net/szhswl/articles/173288.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/szhswl/comments/commentRss/173288.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/szhswl/services/trackbacks/173288.html</trackback:ping><description><![CDATA[在中间件应用服务器的整体调优中，有关于等待队列、执行线程，EJB池以及数据库连接池和Statement Cache方面的调优，这些都属于系统参数方面的调优，本文主要从另外一个角度，也就是从应用的角度来解决中间件应用服务器的内存泄露问题，从这个角度来提高系统的稳定性和性能。
<p><a><span><font face="Arial" color="#000000" size="4">项目背景</font></span></a> </p>
<p><a><span><strong><font face="Arial" color="#000000" size="3">问题描述</font></strong></span></a> </p>
<p>某个大型项目（Use Case用例超过300个），在项目上线后，其Web应用服务器经常宕机。表现为： </p>
<p>1. 应用服务器内存长期不合理占用，内存经常处于高位占用，很难回收到低位； </p>
<p>2. 应用服务器极为不稳定，几乎每两天重新启动一次，有时甚至每天重新启动一次； </p>
<p>3. 应用服务器经常做Full GC(Garbage Collection)，而且时间很长，大约需要30-40秒，应用服务器在做Full GC的时候是不响应客户的交易请求的，非常影响系统性能。 </p>
<p><a><span><strong><font face="Arial" color="#000000" size="3">Web应用服务器的物理部署</font></strong></span></a> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一台Unix服务器（4CPU，8G Memory）来部署本Web应用程序；Web应用程序部署在中间件应用服务器上；部署了一个节点（Node），只配置一个应用服务器实例（Instance），没有做Cluster部署。 </p>
<p><a><span><strong><font face="Arial" color="#000000" size="3">Web应用服务器启动脚本中的内存参数</font></strong></span></a>
<table cellpadding="0" width="100%" border="1">
    <tbody>
        <tr>
            <td bgcolor="#f4f4f4">MEM_ARGS="-XX:MaxPermSize=128m -XX:MaxNewSize=512m -Xms3096m <br />
            -Xmx3096m -XX:+Printetails -Xloggc:./inwebapp1/gc.$$" </td>
        </tr>
    </tbody>
</table>
</p>
<p>可以看出目前生产系统中Web应用服务器的内存分配为3G Memory。 </p>
<p><a><span><strong><font face="Arial" color="#000000" size="3">Web应用服务器的重要部署参数</font></strong></span></a>
<table cellpadding="4" border="1">
    <tbody>
        <tr>
            <td>参数名称 </td>
            <td>参数值 </td>
            <td>参数解释 </td>
        </tr>
        <tr>
            <td>kernel.default(Thread Count) </td>
            <td>120 </td>
            <td>执行线程数目，是并发处理能力的重要参数 </td>
        </tr>
        <tr>
            <td>Session Timeout </td>
            <td>240分钟（4小时） </td>
            <td>HttpSession会话超时</td>
        </tr>
    </tbody>
</table>
</p>
<p>&nbsp; </p>
<p><a><span><font face="Arial" color="#000000" size="4"><strong>分析</strong></font></span></a> </p>
<p><a><span><strong><font face="Arial" color="#000000" size="3">分析方法</font></strong></span></a> </p>
<p>内存长期占用并导致系统不稳定一般有两种可能： </p>
<p>1. 对象被大量创建而且被缓存，在旧的对象释放前又有大量新的对象被创建使得内存长期高位占用。 </p>
<ul>
    <li>表现为：内存不断被消耗、在高位时也很难回归到低位，有大量的对象在不断的创建，经过很长时间后又被回收。例如：在HttpSession中保存了大量的分页查询数据，而HttpSession的会话超时时间设置过长（例如：1天），那么在旧的对象释放前又有大量新的对象在第二天产生。
    <li>解决办法：对共享的对象可以采用池机制进行缓存，避免各自创建；缓存的临时对象应该及时释放；另一种办法是扩大系统的内存容量。 </li>
</ul>
<p>2. 另一种情况就是内存泄漏问题 </p>
<ul>
    <li>表现为：内存回收低位点不断升高（以每次内存回收的最低点连成一条直线，那么它是一条上升线）；内存回收的频率也越来越高，内存占用也越来越高，最终出现"Out of Memory Exception"的系统异常。
    <li>解决办法：定位那些有内存泄漏的类或对象并修改完善这些类以避免内存泄漏。方法是：经过一段时间的测试、监控，如果某个类的对象数目屡创新高，即使在JVM Full GC后仍然数目降不下来，这些对象基本上是属于内存泄漏的对象了。 </li>
</ul>
<p><a><span><strong><font face="Arial" color="#000000" size="3">问题定位</font></strong></span></a> </p>
<p>这里请看5月份 Web应用服务器的内存回收图形： </p>
<p>《注意：5月18日早上10点重新启动了Web服务器，5月20日早上又重新启动了Web服务器。》 </p>
<ul>
    <li>在Web应用重要部署参数中，我们知道：Session的超时时间为4个小时，我们在监控平台也观测到：在18日晚上10点左右所有的会话都过期了，从图形一中也能看出18日晚上确实系统的内存有回收到40%（就象股票的高位跳水）；
    <li>从图形一（5月18日）中我们也能看到Full GC回收后的内存占用率走势（红色曲线），上午基本平滑上升到20%（内存占用率），中午开始上升到30%，下午上升到40%
    <li>从图形二（5月19日）中我们也能看到Full GC回收后的内存占用率走势（红色曲线），上午又上升到了60%，到下午上升到了70%。
    <li>从黄色曲线（GC花费的时间，以秒为单位），Full GC的频率也在增快，时间耗费也越来越长，在图形一中基本高位在20秒左右，到19日基本都是30-40秒之间了。 </li>
</ul>
<p>&nbsp;<a><strong><font color="#000000">图形一 5月18日</font></strong></a><br />
<img height="318" alt="图形一 5月18日" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image002.gif" width="554" border="0" _counted="undefined" /><br />
<br />
<a><strong><font color="#000000">图二</font></strong></a><br />
<img height="320" alt="图二" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image004.gif" width="554" border="0" _counted="undefined" /><br />
</p>
<p>通过上述分析，我们基本定位到了Web应用服务器的内存在高位长期占用的原因了：是内存泄露！并且正是由于这个原因导致系统不稳定、响应客户请求越来越慢的。 </p>
<p><a><span><strong><font face="Arial" color="#000000" size="3">解决方法</font></strong></span></a> </p>
<p>方法如下： </p>
<ul>
    <li>我们从图形二中发现，在8.95(将近9点钟)到9.66（将近9点40）期间有几次Full GC，但是有内存泄漏，从占用率40%上升到50%左右，泄漏了大约10%的内存，约300M；
    <li>我们在自己搭建的Web应用服务器平台（应用软件版本和生产版本一致）做这一阶段相同的查询交易；表明对同一个黑盒（Web应用）施加同样的刺激（相同的操作过程和查询交易）以期重现现象；
    <li>我们使用Jprofiler工具对Web应用服务器的内存进行实时监控；
    <li>做完这些交易后，用户退出系统，并等待Web应用服务器的HttpSession超时（我们这里设置为15分钟）；
    <li>我们对Web应用服务器做了两次强制性的内存回收操作。 </li>
</ul>
<p>发现如下： </p>
<p><br />
<a><strong><font color="#000000">图三</font></strong></a><br />
<img height="392" alt="图三" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image007.gif" width="554" border="0" _counted="undefined" /><br />
</p>
<p>如图三所示，内存经过HttpSession超时后，并强制gc后，仍然有大量的对象没有释放。例如：gov.gdlt.taxcore.comm.security.MenuNode，仍然有807个实例没有释放。 </p>
<p>我们继续追溯发现，这些MenuNode首先存放在一个ArrayList对象中，然后发现这个ArrayList对象又是存放在WHsessionAttrVO对象的Map中，WHsessionAttrVO 对象又是存放在ExternalSessionManager的staic Map中（名称为sessionMap），如图四所示。 </p>
<p><br />
<a><strong><font color="#000000">图四</font></strong></a><br />
<img height="260" alt="图四" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image009.gif" width="554" border="0" _counted="undefined" /><br />
</p>
<p>我们发现gov.gdlt.taxcore.taxevent.xtgl.comm.WHsessionAttrVO中保存了EJBSessionId信息(登录用户的唯一标志，由用户id+登录时间戳组成，每天都不同)和一个HashMap，这个HashMap中的内容有： </p>
<ul>
    <li>ArrayList: 内有MenuTreeNodes（菜单树节点）
    <li>HashMap: 内有操作人员代码信息
    <li>CurrentVersion:当前版本号
    <li>CurrentTime:当前系统时间 </li>
</ul>
<p>WHsessionAttrVO这个对象的最终存放在ExternalSessionManager的static Map sessionMap中，由于ExternalSessionManager是一个全局的单实例，不会释放，所以它的成员变量sessionMap中的数据也不会释放，而Map中的Key值为EJBSessionId，每天登录的用户EJBSessionId都不同，就造成了每天的登录信息（包括菜单信息）都保存在sessionMap中不会被释放，最终造成了内存的泄漏。 </p>
<p><br />
<a><strong><font color="#000000">图五</font></strong></a><br />
<img height="151" alt="图五" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image011.jpg" width="502" border="0" _counted="undefined" /><br />
</p>
<p>如上图所示：WHsessionAttrsVO对象中除了有一个String对象（内容是EJBSessionId），还有一个HashMap对象。 </p>
<p><br />
<a><strong><font color="#000000">图六</font></strong></a><br />
<img height="264" alt="图六" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image013.gif" width="516" border="0" _counted="undefined" /><br />
</p>
<p>如上图所示，这个HashMap中的内容主要有menuTreeNodes为key，value为ArrayList的对象和以czrydminfo为key，value为HashMap对象的数据。 </p>
<p><br />
<a><strong><font color="#000000">图七</font></strong></a><br />
<img height="299" alt="图七" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image015.jpg" width="596" border="0" _counted="undefined" /><br />
</p>
<p>如上图所示：menuTreeNodes为key，value为ArrayList对象中包含的对象有许多的MenuNode对象，封装的都是用户的菜单节点。 </p>
<p><br />
<a><strong><font color="#000000">图八</font></strong></a><br />
<img height="116" alt="图八" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image017.jpg" width="384" border="0" _counted="undefined" /><br />
</p>
<p>如上图所示，最顶层（Root）的初始对象为一个ExternalSessionManager对象，其中的一个成员变量为static (静态的)，名称为：sessionMap，这个对象是singleton方式的，全局只有一个。 </p>
<p><a><span><strong><font face="Arial" color="#000000" size="3">初步估量</font></strong></span></a> </p>
<p>我们从图形一和图形二中可以看出，每天应用服务器损失大约40%的内存，大约1G左右。 </p>
<p>从图形四可以看出，当前用户（Id=24400001129）有807个菜单项（每个菜单项为一个MenuNode 对象实例，图形四中的这个实例的size为592 Byte），这些菜单数据和用户基本登录信息（czrydmInfo HashMap）也都存放在WHsessionAttrVO对象中，当前这个WHsessionAttrVO对象的size为457K。 </p>
<p>我们做如下估算： </p>
<p>假设平均每天有4千人（估计值，这个数值仅仅是5月19日峰值的1/2左右）登录系统（有重复登录的现象，例如：上午登录一次，中午退出系统，下午登录一次），以平均每人占用200K（估计值，是用户id=24400001129 的Size的1/2左右）来计算，一天泄漏的内存约800M，比较符合目前内存泄漏的情况。当然，这种估计仍然需要经过实践的检验，方法是：当这次发现的内存泄漏问题解决后看系统是否还有其它内存泄漏问题。 </p>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img class="magplus" title="点击查看原始大小图片" height="0" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="700" _counted="undefined" /></td>
        </tr>
    </tbody>
</table>
<a><span><font face="Arial" color="#000000" size="4">方案</font></span></a> </p>
<p>ExternalSessionManager类是当初某某软件商设计的用来解决Web服务器负载均衡的模块，这个类主要用来保存客户的基本登录信息（包括会话的EJBSessionId），以维护多个Web服务器之间的会话信息一致。 </p>
<p>改进方案有两种： </p>
<ul>
    <li>
    <p>从架构设计方面改进 </p>
    <p>实现Web层的负载均衡有很多标准的实现方式。例如：采用负载均衡设备(硬件或软件)来实现。 </p>
    <p>如果采用新的Web层的负载均衡方式，那么就可以去掉ExternalSessionManager这个类了。 </p>
    <li>
    <p>从应用实现方面改进 </p>
    <p>保留当前的Web层的负载均衡设计机制，仅仅从应用实现方面解决内存泄漏问题，首先菜单信息不应该保存在ExternalSessionManager中。其次，增加对ExternalSessionManager类中用户会话登录信息的清除，有几种方式可以选择： </p>
    <ul>
        <li>被动方式，当HttpSession会话超时（或过期）被Web应用服务器回收时清除相应的ExternalSessionManager中的过期会话登录信息。
        <li>主动方式，可以采用任务定时清理每天的过期会话登录信息或线程轮询清理。
        <li>采用新的会话登录信息存储方式，ExternalSessionManager的sessionMap中的key值不再以EJBSessionId作为键值，而是以用户id（EJBSessionId的前11位）代替。由于用户id每天都是一样的，所以不会造成内存泄漏。保存得登录信息也不再包含菜单节点信息，而只是登录基本信息。最多也只是保存整个系统所有的用户id及其基本登录信息（大约每个用户的登录信息只有1.5K左右，而目前这个系统的营业网点用户为1万左右，所以大约只占用Web服务器15M内存）。 </li>
    </ul>
    </li>
</ul>
<p><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img class="magplus" title="点击查看原始大小图片" height="0" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="700" _counted="undefined" /></td>
        </tr>
    </tbody>
</table>
<a><span><font face="Arial" color="#000000" size="4">实施情况</font></span></a> </p>
<p>采用的方案：某某软件商采用了新的会话登录信息存贮方案，即:ExternalSessionManager的成员变量sessionMap中不再保存用户菜单信息，只保存基本的登录信息；存储方式采用用户id（11位）作为键值（key）来保留用户基本登录信息。 </p>
<p>基本分析：由于基本登录信息只有1K左右，而目前内网登录的用户总数也只有8887个，所以只保存了大约10M-15M的信息在内存，占用量很小，并且不会有内存泄漏。用户菜单信息保存在session中，如果用户退出时点击logout页面，那么应用服务器可以很快地释放这部分内存；如果用户直接关闭窗口，那么保存在session中的菜单信息只有等会话超时后才会由系统清除并回收内存。 </p>
<p>监控状况： </p>
<p><br />
<a><strong><font color="#000000">图九</font></strong></a><br />
<img height="378" alt="图九" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image019.jpg" width="622" border="0" _counted="undefined" /><br />
</p>
<p>如图九所示，ExternalSessionManager中只保留了简单的登录信息（Map中保存了WHsessionAttrVO对象），包括：当前版本(currentversion)，操作人员代码基本信息（czrydmInfo），当前时间（currenttime）。 </p>
<p><br />
<a><strong><font color="#000000">图十</font></strong></a><br />
<img height="164" alt="图十" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image021.jpg" width="553" border="0" _counted="undefined" /><br />
</p>
<p>如图十所示，这个登录用户的基本信息只有1368 bytes，大约1.3K </p>
<p><br />
<a><strong><font color="#000000">图十一</font></strong></a><br />
<img height="281" alt="图十一" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image023.jpg" width="658" border="0" _counted="undefined" /><br />
</p>
<p>如图十一所示，一共有两个用户（相同的用户id）登录系统，当一个用户使用logout页面退出时，保留在session中的菜单信息(MenuNode)立刻释放了，所以Difference一栏减少了806个菜单项。 </p>
<p><br />
<a><strong><font color="#000000">图十二</font></strong></a><br />
<img height="256" alt="图十二" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image025.jpg" width="604" border="0" _counted="undefined" /><br />
</p>
<p>如图十二所示，当另外一个会话超时后，应用服务器回收了整个会话的菜单信息（MenuNode），图上已经没有MenuNode对象了。并且由于是同一个用户登录，所以保留在ExternalSessionManager成员变量sessionMap中的对象WHsessionAttrVO只有一个(id=24400001129)，而没有产生多个，没有因为多次登录而产生多个对象的后果，避免了内存泄漏问题的出现，解决了前期定位的内存泄漏问题。 </p>
<p><br />
<a><strong><font color="#000000">图十三</font></strong></a><br />
<img height="335" alt="图十三" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image027.jpg" width="451" border="0" _counted="undefined" /><br />
</p>
<p>如图十三所示，经过gc内存回收后，发现内存回收比较稳定，基本都回收到了最低点，也证明了内存没有泄露。 </p>
<p>结论与建议：从测试情况看，解决了前期定位的内存泄漏问题。 </p>
<p><strong>生产系统实施后的监控与分析</strong> </p>
<p>经过调优后，我们发现：在2005年6月2日晚9点40左右重新部署、启动了Web应用服务器（采用了新的调优方案）。经过几天的监控运行，发现Web应用服务器目前运行基本稳定，目前没有出现新的内存泄漏问题，下列图示说明了这一点 </p>
<p><br />
<a><strong><font color="#000000">图十四 2005年6月2日</font></strong></a><br />
<img height="224" alt="图十四 2005年6月2日" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image029.gif" width="554" border="0" _counted="undefined" /><br />
</p>
<p>如图十四所示，6月2日晚21.7（21点42分）重新启动应用服务器，内存占用很少，大约为15%（请看红色曲线），每次GC消耗的时间也很短，大约在5秒以内（请看黄色曲线）。 </p>
<p><br />
<a><strong><font color="#000000">图十五 2005年6月3日周五</font></strong></a><br />
<img height="248" alt="图十五 2005年6月3日周五" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image031.gif" width="553" border="0" _counted="undefined" /><br />
</p>
<p>如图十五所示，在6月3日周五的整个工作日内，内存的回收基本到位，回收位置控制在20%-30%之间，也就是在600M-900M之间（请看红色曲线的最低点），始终可以回收2G的内存供应用程序使用，每次GC的时间最高不超过20秒，Full GC平均在10秒左右，时间消耗比较短（请看黄色曲线）。 </p>
<p><br />
<a><strong><font color="#000000">图十六2005年6月5日周日</font></strong></a><br />
<img height="198" alt="图十六2005年6月5日周日" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image033.gif" width="554" border="0" _counted="undefined" /><br />
</p>
<p>如图十六所示，在周日休息日期间，Web应用服务器全天只做了大约4次Full GC（黄色曲线中的小山峰），时间都在10秒以内；大的Full GC后，内存只占用10%，内存回收很彻底。 </p>
<p><br />
<a><strong><font color="#000000">图十七 2005年6月6日周一</font></strong></a><br />
<img height="249" alt="图十七 2005年6月6日周一" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image035.gif" width="554" border="0" _counted="undefined" /><br />
</p>
<p>如图十七所示，在周一工作日期间，内存回收还是不错的，基本可以回收到30%（见红色曲线的最低点），即：占用900M内存空间，剩余2G的内存空间；Full GC的时间大部分控制在20秒以内，平均15秒（见黄色曲线）。 </p>
<p><br />
<a><strong><font color="#000000">图十八 2005年6月7日周二</font></strong></a><br />
<img height="208" alt="图十八 2005年6月7日周二" src="http://www-128.ibm.com/developerworks/cn/java/j-performance/images/image037.gif" width="554" border="0" _counted="undefined" /><br />
</p>
<p>如图十八所示，在6月7日周二早上，大约8:30左右，Web应用服务器作了一次Full GC，用了10秒的时间，把内存回收到了10%的位置，为后续的使用腾出了90%的内存空间。内存回收仍然比较彻底，说明基本没有内存泄漏问题。 </p>
<p>经过这几天的监控分析，我们可以看出： </p>
<ul>
    <li>Web应用服务器的内存使用已经比较合理，内存在工作日的占用在20%至30%之间，约1G的内存占用，有2G的内存空间富裕；而在空闲时间（周日，每天的凌晨等）内存可以回收到10%，有90%的内存空间富裕；
    <li>Web应用服务器的Full GC的次数明显减少了并且每次Full GC占用的时间也很少，基本控制在10-20秒之间，有的甚至在10秒以内，明显改善了内网应用服务器内存的使用；
    <li>从6月2日重新部署之后，Web应用服务器没有出现宕机重启的现象。 </li>
</ul>
<p><br />
</p>
<p>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img class="magplus" title="点击查看原始大小图片" height="0" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="700" _counted="undefined" /></td>
        </tr>
    </tbody>
</table>
</p>
<p><a><span><font face="Arial" color="#000000" size="4">总结</font></span></a></p>
<p>&nbsp;通过本文，我们可以看到，内存的泄露将会导致服务器的宕机，系统性能就更别说了。对于系统内存泄露问题应该从服务器GC日志方面进行早诊断，使用工具早确认并提出解决方案，排除内存泄露问题，提高系统性能，以规避项目风险。<br />
<br />
本文转自：http://yufeimen.javaeye.com/blog/70721</p>
<img src ="http://www.blogjava.net/szhswl/aggbug/173288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/szhswl/" target="_blank">宋针还</a> 2008-01-07 12:03 <a href="http://www.blogjava.net/szhswl/articles/173288.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JProfiler 解决 Java 服务器的性能跟踪</title><link>http://www.blogjava.net/szhswl/articles/173168.html</link><dc:creator>宋针还</dc:creator><author>宋针还</author><pubDate>Sun, 06 Jan 2008 12:50:00 GMT</pubDate><guid>http://www.blogjava.net/szhswl/articles/173168.html</guid><wfw:comment>http://www.blogjava.net/szhswl/comments/173168.html</wfw:comment><comments>http://www.blogjava.net/szhswl/articles/173168.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/szhswl/comments/commentRss/173168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/szhswl/services/trackbacks/173168.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">作者：徐建祥（<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#110;&#101;&#116;&#112;&#105;&#114;&#97;&#116;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">netpirate@gmail.com</a>）<br />
</span></p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">时间：</span> 2006/01/05<br />
</p>
<p style="margin: 0cm 0cm 0pt">1、摘要..........................................................................1<br />
2、改善服务器的性能...........................................................1<br />
3、分析器原理...................................................................2<br />
4、JProfiler 简介...............................................................2<br />
5、JProfiler 特征...............................................................3<br />
6、本地监控.....................................................................4<br />
7、远程监控.....................................................................7<br />
8、参考..........................................................................9 </p>
<h3 style="margin: 13pt 0cm"><font size="5">1</font> <span style="font-family: 宋体"><font size="5">、</font> </span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">摘要 </span></h3>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; <span style="font-family: 宋体">改善</span> Java <span style="font-family: 宋体">服务器的性能需要模拟负载下的服务器。创建一个模拟环境、搜集数据并且分析结果可能是对许多开发人员的挑战。这篇文章介绍了使用</span> JProfiler <span style="font-family: 宋体">跟踪分析</span> Java <span style="font-family: 宋体">服务器的性能。</span> </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">简单的性能问题很容易分离并解决，然而，大的性能问题，如内存溢出或者系统的罢工，通常在系统处于高负载情况下发生，就不能这么简单的处理了。这些问题需要一个独立的测试环境、一个模拟的负载，并且需要仔细地分析和跟踪。</span> </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">在这篇文章中，我使用比较通用的工具（</span> JProfiler <span style="font-family: 宋体">和</span> JBuilder <span style="font-family: 宋体">）和设备创建了一个性能监控分析环境，跟踪本地和远程的服务器程序，专注于三个性能问题：内存、垃圾回收和多线程运行状况，从而很好的监视</span> JVM <span style="font-family: 宋体">运行情况及其性能。<br />
</span></p>
<h3 style="margin: 13pt 0cm"><span style="font-size: 14pt; line-height: 173%"><font face="Times New Roman">2</font> </span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">、改善服务器的性能 </span></h3>
<p style="margin: 0cm 0cm 0pt; text-indent: 20.6pt"><span style="font-family: 宋体">服务器的性能改善是依赖于数据的。没有可靠的数据基础而更改应用或环境会导致更差的结果。分析器提供有用的</span> <font face="Times New Roman">Java</font> <span style="font-family: 宋体">服务器应用信息，但由于从单用户负载下的数据与多用户负载下得到的数据是完全不同的，这导致分析器的数据并不精确。在开发阶段使用分析器来优化应用的性能是一个好的方式，但在高负载下的应用分析可以取到更好的效果。</span> </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">在负载下分析服务器应用的性能需要一些基本的元素：</span> </p>
<p style="margin: 0cm 0cm 0pt 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt"><font face="Times New Roman">1、<span style="font: 7pt 'Times New Roman'"><font size="3">&nbsp; </font></font></span><span style="font-family: 宋体">可控的进行应用负载测试的环境。</span> </p>
<p style="margin: 0cm 0cm 0pt 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt"><font face="Times New Roman">2、<span style="font: 7pt 'Times New Roman'"><font size="3">&nbsp; </font></font></span><span style="font-family: 宋体">可控的人造负载使得应用满负荷运行。</span> </p>
<p style="margin: 0cm 0cm 0pt 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt"><font face="Times New Roman">3、<span style="font: 7pt 'Times New Roman'"><font size="3">&nbsp; </font></font></span><span style="font-family: 宋体">来自监视器、应用和负载测试工具自身的数据搜集。</span> </p>
<p style="margin: 0cm 0cm 0pt 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt"><font face="Times New Roman">4、<span style="font: 7pt 'Times New Roman'"><font size="3">&nbsp; </font></font></span><span style="font-family: 宋体">性能改变的跟踪。</span> </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 20.6pt"><span style="font-family: 宋体">不要低估最后一个需求（性能跟踪）的重要性因为如果不能跟踪性能你就不能实际的管理项目。性能上</span> <font face="Times New Roman">10-20%</font> <span style="font-family: 宋体">的改善对单用户环境来说并没有什么不同，但对支持人员来说就不一样了。</span> <font face="Times New Roman">20%</font> <span style="font-family: 宋体">的改善是非常大的，而且通过跟踪性能的改善，你可以提供重要的反馈和持续跟踪。</span> </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 20.6pt"><span style="font-family: 宋体">虽然性能跟踪很重要，但有时为了使后续的测试更加精确而不得不抛弃先前的测试结果。在性能测试中，改善负载测试的精确性可能需要修改模拟环境，而这些变化是必须的，通过变化前后的负载测试你可以观察到其中的转变。</span> </p>
<h3 style="margin: 13pt 0cm"><span style="font-size: 14pt; line-height: 173%"><font face="Times New Roman">3</font> </span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">、 </span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">分析器原理 </span></h3>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="color: black; font-family: 宋体">现在几乎所有的分析器都是从同一个起点和约束开始的： </span><span style="color: black; font-family: Arial">Java </span><span style="color: black; font-family: 宋体">虚拟机分析器界面 </span><span style="color: black; font-family: Arial">(JVMPI) ( </span><span style="color: black; font-family: 宋体">参考 </span><span style="color: black; font-family: Arial">"The Java Virtual Machine Profiler Interface") </span><span style="color: black; font-family: 宋体">。 </span><span style="color: black; font-family: Arial">Sun </span><span style="color: black; font-family: 宋体">微系统的 </span><span style="color: black; font-family: Arial">API </span><span style="color: black; font-family: 宋体">允许工具开发商接口或者连接到遵循 </span><span style="color: black; font-family: Arial">JVMPI </span><span style="color: black; font-family: 宋体">的 </span><span style="color: black; font-family: Arial">JVM </span><span style="color: black; font-family: 宋体">上，并且监控运作的方式以及 </span><span style="color: black; font-family: Arial">JVM </span><span style="color: black; font-family: 宋体">运行任何 </span><span style="color: black; font-family: Arial">Java </span><span style="color: black; font-family: 宋体">程序时的关键事件 </span><span style="color: black; font-family: Arial">-- </span><span style="color: black; font-family: 宋体">从单独的应用程序到 </span><span style="color: black; font-family: Arial">Applet </span><span style="color: black; font-family: 宋体">、 </span><span style="color: black; font-family: Arial">Servlet </span><span style="color: black; font-family: 宋体">和企业 </span><span style="color: black; font-family: Arial">JavaBeans (EJB) </span><span style="color: black; font-family: 宋体">组件。 </span><span style="color: black; font-family: Arial"><br />
<br />
</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; color: black; font-family: 宋体">在分析器内启动一个程序意味着生成、捕捉、和观察大量数据，所以所有的分析器都包含着不同的方法来控制数据的流动，在不同的标准以及每一封装包的基础上进行过滤。同样 </span><span style="font-size: 10.5pt; color: black; font-family: 宋体">也可以使用灵活的正规表达式类型模式来完成。 </span></p>
<h3 style="margin: 13pt 0cm"><span style="font-size: 14pt; line-height: 173%"><font face="Times New Roman">4</font> </span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">、 </span><span style="font-size: 14pt; line-height: 173%"><font face="Times New Roman">JProfiler </font></span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">简介 </span></h3>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp002.gif"  alt="" /> <span style="font-family: 宋体">是一个全功能的</span> <font face="Times New Roman">Java</font> <span style="font-family: 宋体">剖析工具（</span> <font face="Times New Roman">profiler</font> <span style="font-family: 宋体">），专用于分析</span> <font face="Times New Roman">J2SE</font> <span style="font-family: 宋体">和</span> <font face="Times New Roman">J2EE</font> <span style="font-family: 宋体">应用程序。它把</span> <font face="Times New Roman">CPU</font> <span style="font-family: 宋体">、执行绪和内存的剖析组合在一个强大的</span> <span style="font-family: 宋体">应用中。</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">可提供许多</span> <font face="Times New Roman">IDE</font> <span style="font-family: 宋体">整合和应用服务器整合用途。</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">直觉式的</span> <font face="Times New Roman">GUI</font> <span style="font-family: 宋体">让你可以找到效能瓶颈、抓出内存漏失</span> <font face="Times New Roman">(memory&nbsp;leaks)</font> <span style="font-family: 宋体">、并解决执行绪的问题。它让你得以对</span> <font face="Times New Roman">heap&nbsp;walker</font> <span style="font-family: 宋体">作资源回收器的</span> <font face="Times New Roman">root&nbsp;analysis</font> <span style="font-family: 宋体">，可以轻易找出内存溢出；</span> <font face="Times New Roman">heap</font> <span style="font-family: 宋体">快照（</span> <font face="Times New Roman">snapshot</font> <span style="font-family: 宋体">）模式让未被参照（</span> <font face="Times New Roman">reference</font> <span style="font-family: 宋体">）的对象、稍微被参照的对象、或在终结（</span> <font face="Times New Roman">finalization</font> <span style="font-family: 宋体">）队列的对象</span> <span style="font-family: 宋体">都会被移除；整合精灵以便剖析浏览器的</span> <font face="Times New Roman">Java</font> <span style="font-family: 宋体">外挂功能。</span> </p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">目前最新的版本是</span> <font face="Times New Roman">4.1.2</font> <span style="font-family: 宋体">，几乎支持所有常用的</span> <font face="Times New Roman">IDE</font> <span style="font-family: 宋体">和</span> <font face="Times New Roman">Application Server</font> <span style="font-family: 宋体">，可以到其</span> <font face="Times New Roman">EJ</font> <span style="font-family: 宋体">官方网站</span> <font face="Times New Roman">http://www.ej-technologies.com/ </font><span style="font-family: 宋体">下载，申请一个十天的试用注册码。</span> </p>
<h3 style="margin: 13pt 0cm"><font face="Times New Roman" size="5">5</font> <span style="font-family: 宋体"><font size="5">、</font> </span><span style="font-size: 14pt; line-height: 173%"><font face="Times New Roman">JProfiler </font></span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">特征 </span></h3>
<h4 style="margin: 0cm 0cm 0pt"><font face="Arial">5.1 </font><span style="font-family: 宋体">内存剖析</span> <font face="Arial">Memory profiler</font> </h4>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left" align="left"><span style="font-family: 宋体">JProfiler</span> <span style="font-family: 宋体">的内存视图部分可以提供动态的内存使用状况更新视图和显示关于内存分配状况信息的视图。所有的视图都有几个聚集层并且能够显示现有存在的对象和作为垃圾回收的对象。</span> </p>
<ul type="disc">
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">所有对象</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示类或在状况统计和尺码信息堆上所有对象的包。你可以标记当前值并显示差异值。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">记录对象 Record objects</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示类或所有已记录对象的包。你可以标记出当前值并且显示差异值。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">分配访问树 Allocation call tree</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一棵请求树或者方法、类、包或对已选择类有带注释的分配信息的J2EE组件。 </span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">分配热点 Allocation hot spots</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个列表，包括方法、类、包或分配已选类的J2EE组件。你可以标注当前值并且显示差异值。对于每个热点都可以显示它的跟踪记录树。 </span></li>
</ul>
<h4 style="margin: 0cm 0cm 0pt"><font face="Arial">5.2 </font><span style="font-family: 宋体">堆遍历</span> <font face="Arial">Heap walker</font> </h4>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left" align="left"><span style="font-family: 宋体">在JProfiler的堆遍历器(Heap walker)中，你可以对堆的状况进行快照并且可以通过选择步骤下寻找感兴趣的对象。堆遍历器有五个视图：</span> </p>
<ul type="disc">
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">类 Classes</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示所有类和它们的实例。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">分配 Allocations</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">为所有记录对象显示分配树和分配热点。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">索引 References</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">为单个对象和&#8220;显示到垃圾回收根目录的路径&#8221;提供索引图的显示功能。还能提供合并输入视图和输出视图的功能。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">数据 Data</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">为单个对象显示实例和类数据。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">时间 Time</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个对已记录对象的解决时间的柱状图。</span> </li>
</ul>
<h4 style="margin: 0cm 0cm 0pt"><font face="Arial">5.3 CPU</font> <span style="font-family: 宋体">剖析</span> <font face="Arial">CPU profiler</font> </h4>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left" align="left"><span style="font-family: 宋体">JProfiler</span> <span style="font-family: 宋体">提供不同的方法来记录访问树以优化性能和细节。线程或者线程组以及线程状况可以被所有的视图选择。所有的视图都可以聚集到方法、类、包或J2EE组件等不同层上。CPU视图部分包括：</span> </p>
<ul type="disc">
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">访问树 Call tree</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个积累的自顶向下的树,树中包含所有在JVM中已记录的访问队列。JDBC,JMS和JNDI服务请求都被注释在请求树中。请求树可以根据Servlet和JSP对URL的不同需要进行拆分。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">热点 Hot spots</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示消耗时间最多的方法的列表。对每个热点都能够显示回溯树。该热点可以按照方法请求，JDBC，JMS和JNDI服务请求以及按照URL请求来进行计算。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">访问图 Call graph</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个从已选方法、类、包或J2EE组件开始的访问队列的图。</span> </li>
</ul>
<h4 style="margin: 0cm 0cm 0pt"><font face="Arial">5.4 </font><span style="font-family: 宋体">线程剖析</span> <font face="Arial">Thread profiler</font> </h4>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left" align="left"><span style="font-family: 宋体">对线程剖析，JProfiler提供以下视图: </span></p>
<ul type="disc">
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">线程历史 Thread history</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个与线程活动和线程状态在一起的活动时间表。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">线程监控 Thread monitor</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个列表，包括所有的活动线程以及它们目前的活动状况。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">死锁探测图表 Deadlock Detection</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个包含了所有在JVM里的死锁图表。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">目前使用的监测器 Current monitor useage</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示目前使用的监测器并且包括它们的关联线程。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">历史检测记录 History usage history</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示重大的等待事件和阻塞事件的历史记录。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">监测使用状态 Monitor usage statistics</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示分组监测，线程和监测类的统计监测数据。</span> </li>
</ul>
<h4 style="margin: 0cm 0cm 0pt"><font face="Arial">5.5 VM </font><span style="font-family: 宋体">遥感勘测技术</span> <font face="Arial">VM telemetry</font> </h4>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left" align="left"><span style="font-family: 宋体">观察JVM的内部状态，JProfiler提供了不同的遥感勘测视图，如下所示: </span></p>
<ul type="disc">
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">堆 Heap</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个堆的使用状况和堆尺寸大小活动时间表。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">记录的对象 Recorded objects</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一张关于活动对象与数组的图表的活动时间表。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">垃圾回收 Garbage collector</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一张关于垃圾回收活动的活动时间表。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">类 Classes</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个与已装载类的图表的活动时间表。</span>
    <li style="margin: 0cm 0cm 0pt; text-align: left; tab-stops: list 36.0pt"><strong><span style="font-family: 宋体">线程 Threads</span> </strong><span style="font-family: 宋体"><br />
    </span><span style="font-family: 宋体">显示一个与动态线程图表的活动时间表。 </span></li>
</ul>
<h3 style="margin: 13pt 0cm"><font face="Times New Roman" size="5">6</font> <span style="font-family: 宋体"><font size="5">、</font> </span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">本地监控 </span></h3>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">系统环境</span> <font face="Times New Roman">Windows OS</font> <span style="font-family: 宋体">；软件</span> <font face="Times New Roman">JBuilderX/2005</font> <span style="font-family: 宋体">和</span> <font face="Times New Roman">JProfiler 4.1.2</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">1</font> <span style="font-family: 宋体">、安装</span> <font face="Times New Roman">JBuilderX</font> <span style="font-family: 宋体">和</span> <font face="Times New Roman">JProfiler 4.1.2</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">2</font> <span style="font-family: 宋体">、运行</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">，</span> <font face="Times New Roman">Session-&gt; </font><span style="font-family: 宋体">IDE integration tab, IDE</span> <span style="font-family: 宋体">选择Borland JBuilder7 to 2005，点击Integrate按钮，选择JBuilder的安装目录，确认，会看到已经将JProfiler以OpenTool的形式，成功整合到JBuilder中，见下图。</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman"><br />
3</font> <span style="font-family: 宋体">、运行</span> <font face="Times New Roman">JBuilder</font> <span style="font-family: 宋体">，打开</span> <font face="Times New Roman">Run-&gt;Configurations</font> <span style="font-family: 宋体">，选择或新建一个</span> <font face="Times New Roman">Runtime</font> <span style="font-family: 宋体">，在</span> <font face="Times New Roman">Optimize</font> <span style="font-family: 宋体">选项中就可以看到</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">，可以选择每次运行程序新建一个</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">窗口的提示设置。</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">4</font> <span style="font-family: 宋体">、点击</span> <font face="Times New Roman">Optimize Project</font> <span style="font-family: 宋体">按钮，运行程序。<br />
</span></p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman"><br />
<img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp004.png"  alt="" /> <br />
<br />
5</font> <span style="font-family: 宋体">、弹出如下的</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">窗口，确认相关的信息即可。<br />
</span></p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman"><br />
<img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp005.png"  alt="" /> <br />
<br />
6</font> <span style="font-family: 宋体">、至此，就可以监控本地服务器的各个方面的性能了。<br />
<img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp006.png"  alt="" /><br />
<br />
<img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp007.png"  alt="" /><br />
<br />
<img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp009.png"  alt="" /><br />
<br />
<img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp010.png"  alt="" /><br />
</span></p>
<h3 style="margin: 13pt 0cm"><font face="Times New Roman" size="5">7</font> <span style="font-family: 宋体"><font size="5">、</font> </span><span style="font-size: 14pt; line-height: 173%; font-family: 宋体">远程监控 </span></h3>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">服务器程序一般运行在远程的服务器设备上，有时候我们还需要远程监控商用的服务器资源。</span> </p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">服务器操作系统</span> <font face="Times New Roman">Linux OS</font> ，安装步骤如下：<br />
<span style="font-family: 宋体">1、./jprofiler_linux_4_1_2.sh，出现如下提示：<br />
testing JVM in /usr/jdk1.4 ...<br />
Starting Installer ...<br />
注：对于没有安装X Server的机器，需要执行./jprofiler_linux_4_1_2.sh -q，否则会提示，<br />
testing JVM in /usr/jdk1.4 ...<br />
Starting Installer ...<br />
This installer needs access to an X Server.<br />
If this is not possible, you can run the installer in unattended mode<br />
by passing the argument -q to the installer.<br />
2、安装完毕后，会在/opt目录下，找到jprofiler的安装目录，<font face="Times New Roman">/opt/jprofiler4。</font><br />
<br />
本地操作系统</span> <font face="Times New Roman">WindowXP</font> <span style="font-family: 宋体">，相关的配置如下：</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">1</font> <span style="font-family: 宋体">、本地安装</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">，</span> <font face="Times New Roman">Linux</font> <span style="font-family: 宋体">服务器上也安装</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">（只有本地</span> <font face="Times New Roman">/</font> <span style="font-family: 宋体">监控者的需要输入序列号）。</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">2</font> <span style="font-family: 宋体">、打开本地的</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">，</span> <font face="Times New Roman">session-&gt;Integration wizards-&gt; New Remote integration</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">3</font> <span style="font-family: 宋体">、选择</span> <font face="Times New Roman">on a remote computer</font> <span style="font-family: 宋体">，</span> <font face="Times New Roman">platform</font> <span style="font-family: 宋体">选择</span> <font face="Times New Roman">linux x86/AMD64</font> <span style="font-family: 宋体">，点击</span> <font face="Times New Roman">next</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">4</font> <span style="font-family: 宋体">、输入远程</span> <font face="Times New Roman">ip</font> <span style="font-family: 宋体">地址，点击</span> <font face="Times New Roman">next</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">5</font> <span style="font-family: 宋体">、输入远程</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">的安装目录，默认都安装在</span> <font face="Times New Roman">/opt/jprofiler4</font> <span style="font-family: 宋体">下，一路NEXT</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">6</font> <span style="font-family: 宋体">、出现下面提示框，按照要求配置下服务器的设置，界面如下：</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman"><img src="http://www.blogjava.net/images/blogjava_net/anymobile/8280/r_jp008.png"  alt="" /> <br />
Java</font> <span style="font-family: 宋体">执行语句中加入下列运行参数</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;-Xint -Xrunjprofiler:port=8849 -Xbootclasspath/a:/opt/jprofiler4/bin/agent.jar</font> <span style="font-family: 宋体">；</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">/etc/profile </font><span style="font-family: 宋体">中加入</span> <font face="Times New Roman">export LD_LIBRARY_PATH=/opt/jprofiler4/bin/linux-x86</font> <span style="font-family: 宋体">，退出、重新登陆。</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">7</font> <span style="font-family: 宋体">、好了，全部配置完毕，先运行远程服务器程序，再打开本地的</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">程序，握手成功后，远程程序正常运行了。</span> </p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">服务器信息如下：</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">[root@ns 55556]# tail -f nohup.out </font></p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Protocol version 21</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Using JVMPI</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; 32-bit library</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Listening on port: 8849.</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Native library initialized</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Waiting for a connection from the JProfiler GUI ...</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">// </font><span style="font-family: 宋体">以上为本地</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">连上前的系统提示</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Using dynamic instrumentation</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Time measurement: elapsed time</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; CPU profiling enabled</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">JProfiler&gt; Starting org/anymobile/server/cmwap/CmwapServer ...</font> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">2005/12/15 17:05:46 [ INFO] - Starting Cmwap Stand Server ...<br />
</font><font face="Times New Roman">2005/12/15 17:05:47 [ INFO] - HandleThread runing ......</font> </p>
<h3 style="margin: 13pt 0cm"><font size="5"><font face="Times New Roman">8</font> <span style="font-family: 宋体">、补充说明及参考 </span></font></h3>
<h4 style="margin: 0cm 0cm 0pt"><font face="Arial">8.1 </font><span style="font-family: 宋体">补充说明</span> </h4>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">如果你希望动态保存当前</span> <font face="Times New Roman">Session</font> <span style="font-family: 宋体">的运行数据的快照，点击</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">的保存按钮即可；</span> </p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">可以通过</span> <font face="Times New Roman">JProfiler Start Center</font> <span style="font-family: 宋体">的</span> <font face="Times New Roman">Open snapshot tab</font> <span style="font-family: 宋体">打开保存的</span> <font face="Times New Roman">Session</font> <span style="font-family: 宋体">；</span> </p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">你也可以右键点击某个视图，静态保存到</span> <font face="Times New Roman">HTML</font> <span style="font-family: 宋体">文件，文字描述加视图图片；</span> </p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">有一些视图的数据只会运行一次，不会动态的刷新，如内存视图中的分配访问树等视图；</span> </p>
<p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">WinXP</font> <span style="font-family: 宋体">下</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">似乎不支持中文，</span> <font face="Times New Roman">2K</font> <span style="font-family: 宋体">下支持的，上面有一些图片是在</span> <font face="Times New Roman">2K</font> <span style="font-family: 宋体">系统上截取的；</span> </p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体">另外，</span> <font face="Times New Roman">JProfiler</font> <span style="font-family: 宋体">还可以监控某个</span> <font face="Times New Roman">Application Server</font> <span style="font-family: 宋体">、</span> <font face="Times New Roman">Applet</font> <span style="font-family: 宋体">，功能非常强大，可以参考软件自带的</span> <font face="Times New Roman">Help</font> <span style="font-family: 宋体">。</span></p>
<img src ="http://www.blogjava.net/szhswl/aggbug/173168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/szhswl/" target="_blank">宋针还</a> 2008-01-06 20:50 <a href="http://www.blogjava.net/szhswl/articles/173168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Optimizeit Profiler概览</title><link>http://www.blogjava.net/szhswl/articles/167377.html</link><dc:creator>宋针还</dc:creator><author>宋针还</author><pubDate>Thu, 13 Dec 2007 01:11:00 GMT</pubDate><guid>http://www.blogjava.net/szhswl/articles/167377.html</guid><wfw:comment>http://www.blogjava.net/szhswl/comments/167377.html</wfw:comment><comments>http://www.blogjava.net/szhswl/articles/167377.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/szhswl/comments/commentRss/167377.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/szhswl/services/trackbacks/167377.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本文通过介绍Optimizeit Profiler的一些主要特征来使你对它有个简要的了解。如果想要知道更多的信息，请查看Optimizeit Profiler用户手册。可以从Optimizeit Profiler单击主菜单info|help来查看所有的使用文档。使用中有何问题，请随时与Borland Technical Support联系。启动应用程序Optimizeit Profil...&nbsp;&nbsp;<a href='http://www.blogjava.net/szhswl/articles/167377.html'>阅读全文</a><img src ="http://www.blogjava.net/szhswl/aggbug/167377.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/szhswl/" target="_blank">宋针还</a> 2007-12-13 09:11 <a href="http://www.blogjava.net/szhswl/articles/167377.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jprobe 使用</title><link>http://www.blogjava.net/szhswl/articles/166322.html</link><dc:creator>宋针还</dc:creator><author>宋针还</author><pubDate>Sat, 08 Dec 2007 11:23:00 GMT</pubDate><guid>http://www.blogjava.net/szhswl/articles/166322.html</guid><wfw:comment>http://www.blogjava.net/szhswl/comments/166322.html</wfw:comment><comments>http://www.blogjava.net/szhswl/articles/166322.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/szhswl/comments/commentRss/166322.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/szhswl/services/trackbacks/166322.html</trackback:ping><description><![CDATA[<h3>jprobe 使用</h3>
<h3>一 介绍</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在Java的广泛应用中，一个关键驱动因素是由于使用标准类库和应用框架从而提高了生产效率。通过减少必要的设计，实现和调试等软件开发任务，Java在各种平台之间极大地改善了集成性和互操作性；其它的开发环境都不能提供象Java那样的强大功能。实际上，没有一个环境象J2EE那样具有明显的基于框架开发的优点，J2EE能够快速地构建可扩展，分布式的安全企业级应用。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;虽然这些优点一直在促进J2EE的空前发展，但也经常出现一些麻烦，那就是人们经常对J2EE应用的性能感到失望。因此，我们需要一些工具和调查策略来帮助J2EE开发团队解决这些性能问题。这就是Quest JProbe Profiler和Jprobe Memory Debugger所要解决的问题。</p>
<p>&nbsp;</p>
<h3>1.1 J2EE性能概揽</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一般情况下，最终用户对J2EE应用性能的体验与下面层次是紧密相关的: </p>
<img height="159" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7.gif" width="235" /><br />
1 J2EE体系结构图
<p>&nbsp;</p>
<li>J2EE应用是指servlets，JSPs，EJBs和支持类，它们在J2EE应用服务器的上下文环境中构成了客户的应用。
<li>J2EE应用服务器是指J2EE应用服务器基础结构的设计，实现和配置，它们提供了客户J2EE应用的上下文环境。
<li>JAVA运行环境是指JAVA虚拟机及其配置(堆的大小等等)的设计和实现。
<li>平台-底层硬件(如CPU的数目，内存的大小，I/O子系统等)和操作系统设计，实现和配置(线程和进程调度，子系统优化，整体负载等) 。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;虽然毫无疑问，底部层次会影响整个性能，经验也不断地表明，性能下降的普遍原因是由组成J2EE应用的Servlets，JSPs和EJBs的设计问题和不佳的实现造成的。本文将集中讨论在这个底层中如何识别出性能下降的原因</p>
<p>&nbsp;</p>
<h3>1.2 概述</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;本文描述了在BEA WebLogic Server6.1上下文环境中，怎样用Quest JProbe Memory Debugger和Profiler分析J2EE应用。包括三个主要部分:</p>
<li>设置-在介绍JProbe的体系结构之后，我们将描述怎样把JProbe Memory Debugger和Profiler集成到WebLogic Server6.1环境中。
<li>对象循环分析-在J2EE应用中，性能下降的普遍原因是创建过多的短期对象(也可称为对象循环)。在这部分里，我们将展示怎样使用JProbe Memory Debugger's Garbage Monitor识别大量创建短期对象的方法。这些是进一步分析减少创建过多对象的最佳方法。
<li>J2EE性能分析-最后，我们将使用JProbe Profiler向你介绍怎样进行J2EE应用的性能分析，并且在语句级上快速地识别出一些耗时最多的方法。
<p>&nbsp;</p>
<h3>2. 集成BEA weblogic 服务器和Quest JProbe</h3>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>2.1 Quest JProbe</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quest JProbe产品线由一族工具组成，该族工具包括下面四个分析工具。</p>
<li>JProbe Memory Debugger-检查Java软件的内存使用情况。
<li>JProbe Profiler-剖析Java软件的性能。
<li>JProbe Threadalyzer-识别线程级的死锁和错误的访问冲突
<li>JProbe Coverage-通过提供的语句级执行信息验证测试框架的完整性。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;虽然本文集中讨论了JProbe Memory Debugger和Profiler，但所有四个工具都采用了相同的体系结构设计，并且与BEA WebLogic服务器的集成方法是相同的。</p>
<p>&nbsp;</p>
<h3>2.1.1 JProbe的体系结构</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一个基于JProbe的调查会话由两个程序组成:</p>
<img height="148" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2.gif" width="495" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图2 JProbe体系结构
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>JProbe控制台</strong>是一个基于Swing的Java应用，它提供了用户图形界面（GUI），用于建立调查会话，在程序运行时查看分析信息和深入分析Snapshot文件中的信息内容。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>测试型Java虚拟机</strong>-JProbe通过JVMPI(Java Virtual Machine Profiling Interface)提供的回调方法，使用标准的Java虚拟机运行Java应用并收集分析信息，该虚拟机是由厂商提供的。在剖析基于WLS的J2EE应用中，Java应用运行在Java虚拟机中，该虚拟机由WebLogic服务器的基本框架组成，就象J2EE应用部署到上面一样。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这种结构具有非常灵活的启动方式。你可以从用户图形界面本身启动测试型Java虚拟机，也可以单独启动测试型Java虚拟机并且使它连接上JProbe控制台。</p>
<p>&nbsp;</p>
<h3>2.2 使用JProbe Application Server Integration Tool</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 启动JProbe Application Server Integration。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 从左上角下拉列表中选择你要集成的BEA Weblogic服务器版本。</p>
<img height="270" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7002.jpg" width="552" /><br />
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 点击"Create"按钮。编辑窗口右边的内容，如图3所示。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 编辑下面区域或使用默认值。</p>
<table width="692" border="1">
    <tbody>
        <tr>
            <td width="164">Integration ID: </td>
            <td width="143">JProbe Demo 1 </td>
            <td width="363">Integration ID ，便于重用每次集成过程 </td>
        </tr>
        <tr>
            <td>Server Directory: </td>
            <td>D:\bea\wlserver6.1 </td>
            <td>直接输入 WLS 服务器根路径或者通过 " 浏览 " 方式输入。 </td>
        </tr>
        <tr>
            <td>Domain Name: </td>
            <td>Mydomain </td>
            <td>输入你想分析的域名。 </td>
        </tr>
        <tr>
            <td>Startup Script: </td>
            <td>StartWeblogic.cmd </td>
            <td>直接输入要调查的服务器的启动脚本或者通过 " 浏览 " 方式输入。 </td>
        </tr>
        <tr>
            <td>JProbe Settings: (JPL File)
            <p>&nbsp;</p>
            </td>
            <td>check the VAR checkbox </td>
            <td>集成工具允许你使用先前创建的 JPL(JProbe Launchpad) 文件。 如果要使用由每个工具在启动时默认创建的 JPL 文件，选择 VAR 复选框。 </td>
        </tr>
        <tr>
            <td>Java Executable: </td>
            <td>d:\sun\jdk1.3.1\bin\Java.exe </td>
            <td>可直接输入或通过浏览方式输入 Java 虚拟机的执行文件路径。 </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5. 点击"Advanced&gt;&gt;"按钮。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6. 填写下面这区域。</p>
<table width="690" border="1">
    <tbody>
        <tr>
            <td width="115">Java Options: </td>
            <td width="170">-classic -mx128m -ms64m </td>
            <td width="383">有选择地给 Java 虚拟机输入参数。 </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7. 点击"Save"按钮。</p>
<p><img height="270" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7002-b.jpg" width="553" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图 4 ． JProbe Application Server Intergation 窗口</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;你已经成功创建和BEA Weblogic6.1的集成， 所有四个工具都可以使用这个集成过程。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8. 点击"Close"按钮。</p>
<p>&nbsp;</p>
<h3>3. 识别J2EE应用性能下降</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JProbe Memory Debugger能帮助你追踪到游离对象（loitering objects）和减少创建过多的对象，并且JProbe Profiler能帮助你发现性能瓶颈。根据具体情况，需要具体分析。在这里，我们简单地概括用于解决对象循环和性能瓶颈这两个常见问题的步骤。更多的信息和其它使用JProbe Memory Debugger和Jprobe Profiler的方法，可以参考在线帮助或者阅读JProbe Memory Debugger Guide和JProbe Profiler Developer's Guide。</p>
<p>&nbsp;</p>
<h3>3.1 对象循环（Object Cycling）</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Java应用性能下降的一个主要原因是创建过多的对象 (或称为对象循环)。Java虚拟机分配了过多的内存，创建了不必要的对象并对这些对象的初始化，加大了垃圾回收活动，从而引起性能下降。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;作为一个性能分析人员，你首先需要识别出创建大量短期对象的方法。这些方法是进一步做减少创建对象数量分析的理想入手点。。JProbe Memory Debugger提供的一个垃圾监视功能可以把对象和分配它们的方法连接起来，并且当你的应用运行时，可以追踪有多少对象已经被垃圾回收了。</p>
<p>&nbsp;</p>
<h3>3.1.1 启动JProbe Memory Debugger的研究会话</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 启动JProbe Memory Debugger。当欢迎界面出现的时候，点击"Run"开始启动。</p>
<p><img height="400" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-5.jpg" width="283" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图 5 ． JProbe 欢迎界面 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 在JProbe LaunchPad窗口中:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a． 选择"Using Application Server"</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b． 从"Application Server"下拉的菜单中选择BEA Weblogic6.1</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c． 注意在"Integration ID"下拉的菜单中填写JProbe Demo 1</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 选择"Filter"</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a． 点击"Please enter a package，or method to display data for"。输入你要调查的包:profiler.com.quoteme.stockwatch</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b． 在"Display"栏的下拉菜单里选择"Display"</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 选中"Monitor Garbage Collections from Program Start"复选框。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. 选择"Snapshot Directory:"为d:\temp。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6. 点击"Run"按钮。</p>
<p><img height="325" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-4.jpg" width="325" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图7．JProbe LaunchPad Pad窗口</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当WebLogic Server初始化时，Runtime Heap Graph将增高，这反映了对象创建和垃圾回收活动。一旦WebLogic Server已经被充分初始化后，你就可以开始着手分析了。</p>
<p>&nbsp;</p>
<h3>3.1.2 运行时交互</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一旦WebLogic Server已经充分初始化，选择你想要用于分析对象循环的应用用例。选择Grabage Monitor标签，按下面的步骤:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 首先运行一次Garbage Collection ，回收在Java堆中分配的，但不再使用的对象。Garbage Monitor表随时更新反映这些被回收对象的情况。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 点击"Clear Table"清空Garbage Monitor表。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 运行你的应用用例。当Java虚拟机开始垃圾回收时，Grabage Monitor表将随之更新。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;提示:在Heap Usage Chart中寻找负载峰值。急剧升降的负载峰值意味着一些对象在被垃圾回收之前只存活了很短的时间。连在一起的一些急剧升降的负载峰值是一个明确的信号，意味着是一个对象循环问题。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 在完成你应用用例后，再次运行Garbage Collection ，回收最后分配但不再使用的对象。</p>
<p>&nbsp;</p>
<h3>3.1.3 分析结果</h3>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当会话结束时，Garbage Monitor中包含了已回收最多实例的前十个类。通常，这些类不是你自己应用的类，准确地说，它们是被你的一些方法(直接地或间接地)分配的第三方的类。最后一列是分配这些已回收对象的方法名。</p>
<img height="201" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-6.jpg" width="553" />
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;提示:如果被不同方法分配的实例属于同一个类，并且都是前十个类的话，你将见到两行相同的类。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 使用Filter Allocating Methods，只显示你包中的一些方法，屏蔽掉其它包中的方法。在我们的例子中，客户J2EE应用定义在profiler.com.quoteme.stockwatch包里面，所以我们把过滤规范profiler.com.quoteme.stockwatch.*.*输入到Filter Allocating Methods文本输入控制中。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 在GC'ed列中，你能看到你的方法分配了多少实例。作为比较，查看Alive列就能看到还有多少实例仍在堆中。Java开发者通常会对创建和移走了多少对象而感到惊奇。</p>
<p>3. 现在你已经识别到你有问题的方法。想想你可能怎样修改这些分配对象的方法，从而减少或排除对象循环？例如，你可以尝试重用某个对象或者创建一个可重用的对象池。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. WebLogic Server6.1编译JSP后，自动产生了一个servlet类名，并赋予一个包名和类名。例如，如果有一个名为TestJSP.jsp的JSP文件，将被编译成名为jsp_servlet.__testjsp的类(JSP名跟着两个下划线，并且都是小写字母)。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用Filtering Classes为jsp_servlet.*限制Garbage Monitor中的内容，可以看到已经被垃圾回收到Garbage Monitor中的JSP。在Filtering Allocating Methods设置jsp_servlet.*.*或jsp_servlet._&lt;你的JSP名&gt;.* 限制Garbage Monitor中的内容，可以从分配的角度在指定的JSP中查看垃圾回收对象。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>更深入的研究</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果你分配的方法没有一个出现在Garbage Monitor中，或者在修改明显的问题后，仍然有对象循环的问题；你需要进行堆栈跟踪，检查哪个方法的调用导致了创建实例并分配了空间。需要使用heap snapshot查看堆栈跟踪。要了解更多的信息，请看在线帮助里的<strong>Garbage Collection Tutorial</strong>或者<strong>JProbe Memory Debugger Developer's Guide</strong>。</p>
<p><br />
<table cellspacing="0" cellpadding="0" width="94%" border="0">
    <tbody>
        <tr>
            <td>
            <h1><img height="35" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/library.gif" width="275" /><br />
            <br />
            </h1>
            <img height="60" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/speek7_b.gif" width="500" /> <br />
            <p>&nbsp;</p>
            <h3>3.2 性能分析</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;解决对象循环问题有助于性能的改进，但你可能仍然面临着性能瓶颈。进行一次性能分析可帮助你在J2EE应用中识别低效率的算法。JProbe Profiler提供了应用的方法级和源代码行级度量值。</p>
            <p>&nbsp;</p>
            <h3>3.2.1 启动JProbe Profiler调查会话。</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 启动JProbe Profiler。当欢迎界面出现时，点击"Run"开始。 </p>
            <img height="400" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-1.jpg" width="283" />
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图9。JProbe欢迎窗口</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 在JProbe LaunchPad窗口中:</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a. 选择"Using Application Server"</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b. 从Application Server下拉菜单中选择BEA Weblogic6.1 </p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c. 注意在Integration ID下拉菜单中填JProbe Demo 1"</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 选择Filter</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a. 点击Please enter a package，class，or method to display data for。输入你要调查的包profiler.com.quoteme.stockwatch</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d. 从Detail Level列的下拉菜单中选择Line Lever</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个元素定义了我们想要把所有运行在环境中的Java软件看作基础结构。因为我们不想详细了解它们的性能信息 (我们只是想知道在代码上的影响，我们不想更细地分析) 提示:在WLS6.1中的JSP Profiling </p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当JSP被WebLogic Server6.1编译时，产生的servlet被给予一个产生的包和类名。例如，如果有一个名为TestJSP.jsp的JSP文件，它被编译后，生成名为jsp_servlet._testjsp的类(两个底线被JSP名跟着，都是小写字母)。 如果你想跟踪你的JSP里的方法在执行中花了多少时间，你必须指定正确的过滤策略，用于捕获数据。 </p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. 选择"CPU Time"</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6. 选择"Record Performance at Program Start"复选框</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7. 选择"a Snapshot Directory:"为d:\temp</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8. 点击"Run"按钮</p>
            <img height="478" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-2.jpg" width="552" />
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图11。 JProbe Profiler LaunchPad窗口</p>
            <p><h></h>3.2.2 运行时交互 </p>
            <h3>&nbsp;</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在性能分析中，Heap Usage Chart就象一个执行进度的监视器，与上节介绍的Garbage Monitor不同，这里不提供类似的运行时性能信息。使WebLogic Server自己初始化到完全启动。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;作为对象循环分析，我们推荐使用应用级的，以用例为中心的方法进行性能分析，具体如下:</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 清空累积的性能数据<img height="34" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-3.gif" width="37" />。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 运行你的应用用例。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 执行一次性能快照<img height="32" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-4.gif" width="37" />，保存性能信息。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;性能快照包括时间和在用例运行期间对象创建等度量数据(这个运行期间从重新设置性能信息开始-第一步，一直到执行快照结束，第三步)。</p>
            <p>&nbsp;</p>
            <h3>3.2.3 解释结果</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JProbe Profiler提供两个工具，以不同的格式显示收集到的数据；可根据具体情况选择:</p>
            <li><strong>Method List</strong>是指以表的形式显示与方法有关的数据信息。使用Method List可以按照名称或度量值排序，或显示只显示其中部分方法。
            <li><strong>Call Graph</strong>--是指以有向图的形式显示方法。可以使用Call Graph查看并跟踪程序中方法间的调用关系。
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从Method List或Call Graph中，你能使用下面这些工具深入到更多的细节数据。</p>
            <li><strong>Method Detail View</strong>是指对于所选的方法，显示它们是被哪些方法(也称父方法)调用了或它们调用了哪些方法(也称子方法)。
            <li><strong>Source Window</strong>显示所选方法的语句级性能信息。
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <h3>3.2.3.1 Time and Object Creation Metrics</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JProbe Profiler在方法方面收集了三个基本度量值:</p>
            <li>Number of Calls是指在会话期间该方法被调用的次数
            <li>Method Time是指执行该方法所花费的总时间
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method Objects是指该方法创建的对象总数</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在这些基本的度量值基础上，JProbe Profiler计算出两种度量值表示方法调用树:</p>
            <li>Cumulative Time是指执行这些方法的时间，和执行它们直接或间接调用的方法所花费时间的总和。
            <li>Cumulative Objects是指这些方法创建的对象，和这些方法直接或间接调用其它方法创建的对象的总合
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;基于Number of Calls用四种平均度量值:</p>
            <li>Avg.Method Time是指调用方法的时间除以调用次数
            <li>Avg.Method Objects是指方法对象除以调用次数（方法对象指方法执行期间创建的对象数，不包括派生对象创建的数）
            <li>Avg.Cumulative Time是指累积时间除以调用次数
            <li>Avg.Cumulative Objects是指累积对象除以调用次数
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在默认情况下，Call Graph显示的数据是在性能快照中的数据。我们建议你关闭Call Graph一会再打开Method List窗口。</p>
            <p>&nbsp;</p>
            <h3>3.2.3.2 Method List</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method List窗口(见图12)以表的形式显示性能数据。</p>
            <img height="336" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-5.jpg" width="553" />
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图12。JProbe Profiler Method List窗口</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每一行显示了方法的时间和方法创建对象的度量值。使用Method List能很快识别你最耗时的方法。通常你会发现你的性能瓶颈和这些方法有关。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果你是第一次调查，跟着下面这些步骤将使你能更有效地使用Method List。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 选中你的snapshot，打开"Method List"。<img height="36" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-6.gif" width="39" /></p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. "Filter"区域只用于显示在你包中或在你感兴趣的类中的方法。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 点击"Method Time"列名，把你最消耗时间的方法排在最前面。仔细查看前十个。是不是有一些度量值令你惊讶?你能改进你方法中的算法吗?</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 点击"Cumulative Time"列名，把最消耗时间的调用树排在最前面。比较一下"Method Time"和"Cumulative Time"。虽然方法本身可能效率很高，但也可能调用了低效率的方法，这些低效率的方法可能在你的代码中，或者在第三方的包或应用框架中。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. 点击"Number of Calls"列名，查看一下你哪个方法被调用最多。如果一个或多个度量值同时反映这些方法是低效率的，需要考虑减少调用这些方法，或调用那些效率稍好的方法。</p>
            <p>&nbsp;</p>
            <h3>3.2.3.3. Call Graph</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call Graph(见图13)提供一个非常有力的方法调用关系视图。它把J2EE应用放到WebLogic Server上下文环境中，所以你能看到WebLogic启动的所有线程，包括调用J2EE应用的线程。为了方便查找，Call Graph下面有"Method List"。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当分析性能时，在定位J2EE应用的入口点和排除与WebLogic线程有关的数据方面， Call Method是最有效的。在分离出应用的数据基础上，可快速画出执行流程，并用图形清晰地显示出来。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是使用Call Method的有效技巧:</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 选中你的snapshot，打开"Call Graph"<img height="37" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-7.gif" width="38" />。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 点击"Find"并且定位你的J2EE应用的入口位置。<img height="38" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-8.gif" width="37" />通常是servlet中的doGet()或doPost()方法。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 选择方法并分离出数据形成图形<img height="38" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-9.gif" width="37" />。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 显示方法的一个子集作为开始，这些方法按照"Cumulative Time"排序是最耗时的方法。当你分析一个方法，在方法的调用树上将增加额外的节点。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. 在"Method List"中，根据你发现的瓶颈位置，在"Color By"的下拉列表中选择相同度量值。根据你选择的度量值，现在最耗时的方法都以鲜艳的颜色突出显示出来。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6. 选择最耗时的方法。展开父方法树(通过点击节点部分或节点左边部分的空箭头记号)，就能看到哪个方法调用它了。你可以调用不同的，耗时比较少的方法吗?你需要经常调用这些方法吗?</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7. 展开子方法树(指向节点的右边)，可以看到调用了哪个耗时的方法。还有哪些子方法也是耗时的呢?你意识到第三方的方法实际的耗时情况吗?你能调用一个实现了更有效率算法的不同方法吗?</p>
            <img height="377" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-10.jpg" width="552" />
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图13。JProbe Profiler Call Graph窗口</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从Method List或Call Graph中，你都能深入地分析，在一个视图中很方便地看到耗时的方法的度量值，还有它们子方法和父方法的度量值。选择方法并打开"Method Detail View"<img height="35" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-11.gif" width="38" />。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Method Detail View"(见图14)在窗口的中心显示了选择方法，它的父方法在上面，它的子方法在下面。我们对列的头部已经熟悉了，它们和你在其它工具中看到的度量值相同。一个重要的区别是：用于显示父方法和子方法度量值表示对所选方法的贡献值，不是对它们自己的度量值。所以，如果一个方法被调用了12次，这些调用它的方法，和12次调用分别显示在父方法的图中。如果你想继续分析父方法或子方法，双击该方法，使该方法在"Method Detail View"的中心显示。</p>
            <img height="386" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-12.jpg" width="553" />
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图14 JProbe Profiler Method Detail窗口</p>
            <p>&nbsp;</p>
            <h3>3.2.3.5 Source Window</h3>
            <p>&nbsp;</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;要查看你方法中的代码，选择方法并且打开Source Window。你需要指出你的源代码具体位置。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果你是按行收集数据，你能在Source Window(见图15)中看到这些数据。在左列中，显示了每条语句的数据度量值。行级度量值是方法级度量值的细化，包括调用次数，执行该行的时间，执行该行时创建的对象数量，累积时间和累计对象数量。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>提示:</strong>如果需要编辑你的代码，并且已经把集成开发环境IDE和JProbe Profiler集成在一起了，你可以通过选择Edit&gt;Edit Source打开你的集成开发环境。当然，需要运行你重写的代码，并建立新的JProbe Profiler分析会话时，你做的改变才反映在JProbe Profiler上。</p>
            <img height="345" alt="" src="file:///E:/资料/HTML/jprobe%20使用%20-%20gaojsh69326的专栏%20-%20CSDNBlog.files/sp7-2-13.jpg" width="553" />
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;图15 Jprobe Profiler Source Window</p>
            </li>
            </td>
        </tr>
    </tbody>
</table>
</p>
</li>
<p><span style="font-size: 8pt">本文转自:http://tb.blog.csdn.net/TrackBack.aspx?PostId=599690</span></p>
<img src ="http://www.blogjava.net/szhswl/aggbug/166322.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/szhswl/" target="_blank">宋针还</a> 2007-12-08 19:23 <a href="http://www.blogjava.net/szhswl/articles/166322.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>