Java性能优化全攻略

uuzy5679 8年前
   <p>让Java应用程序运行是一回事,但让他们跑得快就是另外一回事了。在面对对象的环境中,性能问题就像来势凶猛的野兽。但JVM的复杂性将性能调整的复杂程度增加了一个级别。这里Refcard涵盖了JVM internals、class loading(Java8中更新以映射最新的元空间)、垃圾回收、故障诊断、检测、并发性,等等。</p>    <h2>介绍</h2>    <p>Java是目前软件开发领域中使用最广泛的编程语言之一。Java应用程序在许多垂直领域(银行、电信、医疗保健等)中都有广泛使用。Refcard的目的是,帮助开发者通过专注于JVM内部,性能调整原则和最佳实践,以及利用现有监测和故障诊断工具,来提升应用程序在商业环境中的性能。</p>    <p>它能以不同的方式定义“optimal performance(最佳性能)”,但基本要素是:Java程序在业务响应时间要求内执行计算任务的能力,程序在高容量下执行业务功能的能力,并具有可靠性高和延迟低的特点。有时,数字本身变得模式化:对于一些大型网站,优秀的页面响应时间应该在500ms以下。在适当的时候,Refcard包括目标数字。但在大多数情况下,您需要根据业务需求和现有的性能基准自己决定这些。</p>    <h2>JVM Internals</h2>    <p>基础知识</p>    <p><img src="https://simg.open-open.com/show/9003da5e4ef779dad600c58ee13d3f58.jpg"></p>    <p>代码编译和JIT</p>    <p>编译Java字节码显然没有直接从主机执行本机代码那么快。为了提高性能,Hotspot JVM找出最繁忙的字节码区域,然后将其编译成更高效地原生、机器代码(自适应优化)。然后这种本地代码就会存储在非堆内存中的代码缓存中。</p>    <p>注意:多数的JVM是通过禁用JIT编译器实现的(Djava.compiler=NONE)。您只需要考虑禁用的关键性优化,比如JVM崩溃。</p>    <p>下图说明了Java源代码,即时编译流程和生命周期。</p>    <p><img src="https://simg.open-open.com/show/6fee5b6ae9c69bde1da15a1605892950.jpg"></p>    <p>内存空间</p>    <p>HotSpot Java Virtual Machine是由以下的存储空间组成。</p>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>存储空间</strong></td>       <td><strong>描述</strong></td>      </tr>      <tr>       <td>Java Heap</td>       <td>Java程序类实例和数组的主存储器。</td>      </tr>      <tr>       <td> <p>Permanent Generation(JDK 1.7及以下版本)</p> <p>Metaspace (JDK 1.8及以上版本)</p> </td>       <td> <p>Java类元数据的主存储器。</p> <p>注意:从Java 8开始,PermGen空间就由元空间和使用本地存储器替换了,类似于IBM J9 JVM。</p> </td>      </tr>      <tr>       <td>Native Heap(C-Heap)</td>       <td>本地内存存储线程、栈、包括对象的代码缓存,如MMAP文件和第三方本机库。</td>      </tr>     </tbody>    </table>    <h2>类加载</h2>    <p>Java的另一个重要特点是,在JVM启动之后,它能够加载编译的Java类(字节码)。根据程序的大小,在刚刚重启之后,程序在类加载过程中性能会显著降低。这种现象是因为内部JIT编译器在重启之后需要重新开始优化。</p>    <p>自JDK 1.7版本之后,有一些改进值得大家重视。例如默认的JDK class loader具有更好的装在类并发能力。</p>    <p>热点</p>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>关注的区域</strong></td>       <td><strong>建议</strong></td>      </tr>      <tr>       <td>JVM重启后的性能下降</td>       <td>避免部署过量的Java类到一个单一的应用程序类加载器(例如:非常大的WAR文件)</td>      </tr>      <tr>       <td>运行时发现过多的类加载争夺(thread lock, JAR file searches...) ,降低了整体性能。</td>       <td> <p>分析您的应用程序并识别代码模块进行动态类加载操作过于频繁。积极寻找非一站式类加载错误,如ClassNotFoundException和NoClassDefFoundError。</p> <p>再访Java映射API和适用情况下优化的过度使用。</p> </td>      </tr>      <tr>       <td> <p>java.lang.OutOfMemoryError: PermGen space (JDK 1.7及以下版本)</p> <p>java.lang.OutOfMemoryError:元空间(JDK 1.8及以上版本)</p> </td>       <td> <p>再访JVM Permanent Generation、Metaspace (MaxMetaSpaceSize)和本地内存容量在适用情况下的尺寸。</p> <p>分析应用程序类加载器和识别元数据的内存泄漏的源头。</p> </td>      </tr>     </tbody>    </table>    <p><img src="https://simg.open-open.com/show/a831dfdb7b872028bd24b1799ec52ccf.jpg"></p>    <h2>故障诊断和监视</h2>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>目标</strong></td>       <td><strong>建议</strong></td>      </tr>      <tr>       <td>跟踪那些加载到不同的类加载器的Java类。</td>       <td>配置程序选择使用的Java profiler,例如JProfiler或Java VisualVM。将重点放在类加载器的操作和内存占用上。可以通过–verbose:class. for the IBM JVM,生成多个Java核心快照跟踪活动的类加载器和加载类。</td>      </tr>      <tr>       <td>调查类元数据的内存泄露的可以来源。</td>       <td> <p>配置程序和定义可能的culprit(s)。生成并分析JVmheap dump快照,专注于类加载器和java.lang.Class中的实例。</p> <p><img src="https://simg.open-open.com/show/2abbb7aa8ceb9ab3a846200ae31263e9.jpg"></p> </td>      </tr>      <tr>       <td>确保适当的Permanent Generation / Metaspace和本地内存大小。</td>       <td> <p>密切监视你的PermGen、元空间和本机内存利用率,并调整到适合的最大容量。</p> <p>分析程序类加载器的大小,并寻找机会适当地减少元数据足迹。</p> </td>      </tr>     </tbody>    </table>    <h2>垃圾回收</h2>    <p>Java垃圾回收流程对于程序性能是至关重要的。为了提供有效的垃圾回收,Heap(堆)本质上是划分在子区域中。</p>    <p>堆区域</p>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>区域</strong></td>       <td><strong>描述</strong></td>      </tr>      <tr>       <td>最新一代-Young Generation (nursery space)</td>       <td> <p>新的或短暂的对象分配保留堆的一部分。</p> <p>垃圾被一个fast but stop-the-world YG的收集器进行回收。</p> <p>在young space中呆了足够久的对象就会提升到old space。</p> <p>注意:YG space的尺寸和GC频率过高将会显著影响程序的响应时间,从而导致JVM的暂停时间增加。</p> </td>      </tr>      <tr>       <td>老一代-Old Generation  (tenured space)</td>       <td> <p>heap的一部分留给了long-lived对象。</p> <p>垃圾通常通过平行或并发(多数时候)进行收集,诸如CMS或gencon (IBM JVM)。</p> <p>性能提示:根据应用程序的需求选择并测试最佳的GC策略是非常重要的。例如,当切换到并发GC收集(如CMS或G1)可以显著提高应用程序的平均响应时间(减少延迟)。</p> </td>      </tr>     </tbody>    </table>    <p><img src="https://simg.open-open.com/show/3531a9afa5e1aaf5a4365fffd47280f1.jpg"></p>    <p>GC Collectors</p>    <p>选择正确的collector或GC policy可以将程序的性能、可扩展性和可靠性优化到最佳状态。许多应用程序对于响应时间延迟都很敏感,因此大多需要使用并发的回收器,例如HotSpot CMS或IBM GC policy balanced。</p>    <p>我们强烈建议您通过适当的性能和负载测试确定最合适的GC策略。应该在生产环境中执行全面监控策略,以跟踪整体的JVM性能,并确定在之后需要改进的领域。</p>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>GC</strong></td>       <td><strong>论据</strong></td>       <td><strong>描述</strong></td>      </tr>      <tr>       <td>串行回收器</td>       <td>-XX:+UseSerialGC (Oracle HotSpot)</td>       <td> <p>无论新旧回收器都使用单独CPU,像是一种stop the world的时尚。</p> <p><img src="https://simg.open-open.com/show/ffcdd7e56f9576d0404e357808027e76.jpg"></p> </td>      </tr>      <tr>       <td> <p>并行回收器</p> <p>(吞吐量回收器)</p> </td>       <td> <p>-XX:+UseParallelGC</p> <p>-XX:+UseParallelOldGC(Oracle Hotspot)</p> <p>-Xgcpolicy:optthruput(IBmJ9, single space, stop-the-world)</p> </td>       <td> <p>旨在利用CPU的内核优势。无论新旧回收器都使用多个Gcthreads(via –XX:ParallelGCThreads=n),从而更好地利用来自主机的可用的CPU内核来完成。</p> <p>注意:虽然回收时间可以显著减少,但是有着大尺寸堆的程序面临着large、stop-the-world、old回收,并且响应时间也受到影响。</p> <p><img src="https://simg.open-open.com/show/f397ee9083cf0f1eaf9ae4269b6ff15f.jpg"></p> </td>      </tr>      <tr>       <td>确保适当的Permanent Generation / Metaspace和本地内存大小。</td>       <td> <p>密切监视你的PermGen、元空间和本机内存利用率,并调整到适合的最大容量。</p> <p>分析程序类加载器的大小,并寻找机会适当地减少元数据足迹。</p> </td>       <td> <p>旨在最大限度地减少旧一代stop-the-world回收器对程序响应时间的影响。</p> <p>大多数使用CMS collector的老一代回收器与所述应用程序的执行同时进行。</p> <p>注意:YoungGen collections仍然有stop-the-world事件,因此需要适当的微调,以减少总JVM暂停时间。</p> <p><img src="https://simg.open-open.com/show/57e9f32b7ad698fa49bfe05b44372d21.jpg"></p> </td>      </tr>     </tbody>    </table>    <p>Garbage First (G1) Collector</p>    <p>HotSpot G1 collector是专为是专为满足用户定义的垃圾回收(GC)高概率暂停时间设计的,同时实现高吞吐量。</p>    <p>最新的HotSpot collector将heap基本划分到一组大小相等的堆区域,虚拟内存的每个区域连续范围。它将回收压缩的活动集中在heap区域,那里充满了可回收的对象(garbage first)。换句话说就是,这个区域有最低限度的“live”对象。</p>    <p>Oracle建议在以下例子和情况下使用G1 collector,尤其是对于目前正在使用CMS或parallel collectors的:</p>    <ul>     <li>专为large heaps(>= 6 GB),并限制GC延迟(暂停时间<= 0.5秒)的应用程序设计。</li>     <li>超过50%的Java heap被实时数据占用(对象不能被GC回收)。</li>     <li>对象分析率和促进作用显著变化。</li>     <li>不期望过长的垃圾回收或压缩停顿(超过0.5至1秒)。</li>    </ul>    <p><img src="https://simg.open-open.com/show/400e1129e70101f046cfa840aa9d8784.jpg"></p>    <p>Java Heap尺寸</p>    <p>你一定要知道没有GC策略可以挽救Java Heap尺寸不足的现象。这些演习涉及到为不同的存储空间(包括新旧不同的版本)配置最大和最小的容量,包括元数据和本地内存容量。这里有一些建议准则:</p>    <ul>     <li>在32-bit或64-bit JVM之间进行明智的选择。如果程序运行需要超过2GB内存,并且JVM暂停时间在可接受范围内,可以考虑使用64-bit JVM。</li>     <li>永远将应用程序放在第一考虑。确保将其配置好,并根据程序的内存占用量调整heap尺寸。建议通过性能和负载测试来衡量实时数据占有量。</li>     <li>larger heap并不总是表现得更好、更快,因此不需要过度调整Java heap。并行中的JVM性能调优,找准机会减少或“spread”程序的内存占有量,以保证JVM的平均响应时间<1%。</li>     <li>对于32-bit JVM,为了从元数据和本地heap中留出一些内存,考虑2GB的最大heap尺寸。</li>     <li>对于64-bit JVM,我们要想办法在垂直和水平层面进行扩展,而不是试图将Java heap尺寸增加到15GB以上。这种做法往往提供更好的吞吐量,更好地利用硬件,提高应用程序的故障切换功能。</li>     <li>不许重复开发:充分利用开源以及商业故障排除的优势和监控工具,使这些变成可能。APM(应用性能管理)产品在过去十年里发展迅猛。</li>    </ul>    <p>JDK 1.8 Metaspace指南</p>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>目标</strong></td>       <td><strong>建议</strong></td>      </tr>      <tr>       <td> <p>内存大小</p> <p>GC调整</p> <p>监控和故障排除</p> </td>       <td> <p>默认情况下,元空间内存空间是无界的,并使用可用于动态扩展的process或OS native memory。内存空间分成快并通过mmap被JVM进行存储。我们建议保持默认设置,以动态调整模式为出发点,将简化的尺寸与密切监测的应用程序元数据占有量相结合,从而进行更好的容量规划。</p> <p>新增一个JVM选项(-XX:MaxMetaspaceSize= ),可以让您限制分配给class metadata的本地内存。当面临物理资源(RAM)紧张或类似于内存泄露的情况时,建议将它作为一个保障机制。</p> <p>对那种具有larger class metadata footprint或dynamic classloading的Java应用程序,我们建议通过新的JVM选项调整初始元空间大小 :-XX:MetaspaceSize= ,例如:1GB。这种调整方法将有助于避免包括class metadata在内的早期垃圾回收,尤其是在Java应用程序的 “warm-up”期。</p> </td>      </tr>     </tbody>    </table>    <p>Hot Spots</p>    <p><img src="https://simg.open-open.com/show/5c9f7e4caade4b3eebbd05086924e5ab.jpg"></p>    <p>故障诊断和监视</p>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>目标</strong></td>       <td><strong>建议</strong></td>      </tr>      <tr>       <td> <p>测量和监视应用程序YoungGen和OldGen内存占用,包括GC活动。</p> <p>为您的应用程序决定正确的GC策略和Java堆大小。</p> <p>调整应用程序的内存占用量,如live对象。</p> </td>       <td> <p>分析、监控您所使用的Java分析工具,如JProfiler、Java VisualVM或其他商业APM产品。</p> <p>允许通过–verbose:gc记录JVM GC活动。您也可以使用类似GCMV(GC Memory Visualizer)的工具查看JVM的暂停时间和内存分配率。</p> <p>性能提示:过多的内存分配率可能意味着需要进行垂直和横向扩展,或从多个JVM进程中分离出实时数据。</p> <p>为了long-lived对象或long-term实时数据考虑,可以生成并分析JVM heap dump快照。Heap dump分析对于程序内存占用(retention)的优化是非常有帮助的。</p> <p>性能提示:由于从32位到64位,Java应用程序对heap 的需求会比原来高1.5倍。所以,在Java 1.7及以下的版本(这是默认的)中使用 -XX:+UseCompressedOops是非常重要的。这样的参数调整大大减轻了64位JVM的性能压力。</p> </td>      </tr>      <tr>       <td>调查OutOfMemoryError 问题,寻找OldGen内存泄露的根源。</td>       <td> <p>使用类似Java VisualVM、Plumbr的工具(Java内存泄漏检测器),分析可能存在的内容泄露。</p> <p>性能提示:要着重分析最大的Java对象上。要意识到降低内存占有量就意味着提升性能,并降低GC活动。</p> <p><img src="https://simg.open-open.com/show/8be3d32a3db0d8cae2fb74e1405f2233.jpg"></p> <p>使用类似 Memory Analyzer的工具生成并分析JVM heap dump快照。</p> <p><img src="https://simg.open-open.com/show/6390dc03e7d89a256141ac1a83776164.jpg"></p> </td>      </tr>     </tbody>    </table>    <h2>Java并发性</h2>    <p>Java并发性可以定义为程序同时执行多个任务的能力。对于大型的Java EE系统,这意味着执行多个用户的业务功能的同时,实现最佳的吞吐量和性能的能力。</p>    <p>无论是硬件能力还是JVM稳定状况,Java并发性问题可能引起程序的瘫痪,严重影响程序的整体性能和可用性。</p>    <p><img src="https://simg.open-open.com/show/4aa735258dc4f5964fb7868f492ac3a2.jpg"></p>    <p>Thread Lock Contention</p>    <p>当您评估Java应用程序的并发线程的稳定状况时,你会经常遇到Thread lock contention的问题,这是目前最常见的Java并发问题。</p>    <p>例如:Thread lock contention会触发non-stop,它会尝试将一个缺少Java类(ClassNotFoundException的)加载到默认的JDK 1.7 ClassLoader。</p>    <p><img src="https://simg.open-open.com/show/a28635b723767459da1234586665434c.jpg"></p>    <p>如果您在成熟的技术环境中遇见像Thread Dump analysis这样的问题,我们强烈建议您积极面对它。这个问题的根源通常不同于之前的Java synchronization to legitimate IO blocking或者其他的non-thread safe calls。Lock contention问题往往是另一个问题的“症状”。</p>    <p>Java-level Deadlocks</p>    <p>真正的Java-level deadlocks是不太常见的,它同样可以极大程度地影响应用程序的性能和稳定性。当遇到两个或多个线程永远阻塞的时候,就会触发这样的问题。这种情况不同于其他常见的那种“day-to-day”线程问题,例如 lock contention、threads waiting on blocking IO calls等等。真正的lock-ordering deadlock问题可以被看做如下:</p>    <p><img src="https://simg.open-open.com/show/a6dcd15b241d71ccb44d7b692508fa3e.jpg"></p>    <p>Oracle HotSpot 和IBM JVM为大多数的deadlock detectors情况提供了解决方案,帮助您快速找出造成这种状况的罪魁祸首的线程。遇到类似lock contention troubleshooting的问题,建议从诸如线程转储分析为出发点来解决该问题。</p>    <p>一旦找到造成问题的代码根源,解决方案涉及lock-ordering条件寻址和来自JDK其他可用的并发编程技术,如java.util.concurrent.locks.ReentrantLock,提供了诸如tryLock()的方法。这种方法给予开发人员更大的灵活性,也为防止deadlock和thread lock “starvation”提供了更多方式。</p>    <p><img src="https://simg.open-open.com/show/98c49825783cd70735988d920556aedb.jpg"></p>    <p>Clock Time和CPU Burn</p>    <p>在进行JVM调优的同时,也有必要检查应用程序的行为,更确切地说是最高clock time和CPU burn的贡献者。</p>    <p>当Java垃圾回收和线程并发不再是压力点,深入到你的应用程序代码的执行模式,并专注于顶级响应时间贡献者(也叫作clock time)是很重要的。检查应用程序代码的消CPU耗和Java 线程(CPU burn)也同样至关重要。CPU使用率较高(>75%)是不正常的(良好的物理资源的利用率)。因为这往往意味着效率低下和容量问题。对于大型的Java EE企业应用,保持安全的CPU缓冲区是必要的,以应对突发的负载冲击情况。</p>    <p>摒弃那些传统的跟踪方法,如在代码中加入响应时间“日志”。Java剖析工具和APM解决方案恰恰可以帮助您分析这类型的问题。这种方式更加高效、可靠。对于Java生产环境缺乏一个强大的APM解决方案。您仍然可以依赖诸如Java VisualVM的工具,通过多个快照进行thread dump分析,并使用OS CPU分析每个线程。</p>    <p>最后的建议是,不要妄图同时解决所有的问题。列出排在最前面的5个clock time和CPU burn问题,然后寻找解决方案。</p>    <p><img src="https://simg.open-open.com/show/cecf3703e45501598afd999bf0e5d7cb.jpg"></p>    <h2>Application预算</h2>    <p>其他关于Java应用程序性能的重要方面是稳定性和可靠性。在有着99.9%典型可用目标的SLA umbrella下,稳定和可靠对于程序的操作尤为重要。这些系统应该具有高容错级别,并对应用和资源进行严格的预算,以防止发生多米诺效应。用这种方法可以防止一些这样的情况,例如,一个业务流程使用所有可用的物理,中间件或JVM资源。</p>    <p>Hot Spots</p>    <p><img src="https://simg.open-open.com/show/68b4ca410e1892dac30810ab46c63629.jpg"></p>    <p>超时管理</p>    <p>Java application与外部系统之间缺乏合理的超时时间,由于中间件和JVM线程消耗(blocking IO calls),可能导致严重的性能下降和中断。合理的超时时间可以避免在遇到外部服务提供商速度缓慢的时候,Java线程等待太久。</p>    <p><img src="https://simg.open-open.com/show/e52e5290692ca51091a22db20049d75e.jpg"></p>    <h2>工具</h2>    <table align="center" cellspacing="0">     <tbody>      <tr>       <td><strong>目标 </strong></td>       <td><strong>建议工具 </strong></td>      </tr>      <tr>       <td>自动、实时地性能监控、调节、预警、趋势分析、容量管理,等等</td>       <td> <p>Enterprise APM solutions(企业级APM解决方案)</p> <p>注意:APM解决方案提供了工具,这些现成的功能让您实现以下大部分的Java性能目标。</p> </td>      </tr>      <tr>       <td>性能和负载测试</td>       <td> <p>商业性能测试解决方案</p> <p>Apache JMeter</p> <p><a href="/misc/goto?guid=4958849143154880782" rel="nofollow,noindex">http://jmeter.apache.org/</a></p> </td>      </tr>      <tr>       <td>JVM垃圾回收评估,内存分配率和故障排除</td>       <td> <p>Oracle Java VisualVM</p> <p><a href="/misc/goto?guid=4959673284959873871" rel="nofollow,noindex">http://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/intro.html</a></p> <p><a href="/misc/goto?guid=4959673285060959154" rel="nofollow,noindex">http://java.dzone.com/articles/profile-your-applications-java</a></p> <p>Oracle Java Mission Control</p> <p><a href="/misc/goto?guid=4959673285154190601" rel="nofollow,noindex">http://www.oracle.com/technetwork/java/javaseproducts/mission-control/java-mission-control-wp-2008279.pdf</a></p> <p><a href="/misc/goto?guid=4959673285247076658" rel="nofollow,noindex">http://www.oracle.com/technetwork/java/javase/jmc53-release-notes-2157171.html</a></p> <p>IBM Monitoring and Diagnostic Tools for Java(via IBM Support Assistant tool)</p> <p><a href="/misc/goto?guid=4959673285331097827" rel="nofollow,noindex">http://www-01.ibm.com/software/support/isa/</a></p> <p>JVM verbose:gc logs</p> <p>JVM argument : -verbose:gc</p> <p><a href="/misc/goto?guid=4959631336793533962" rel="nofollow,noindex">http://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html</a></p> <p>IBM GCMV</p> <p><a href="/misc/goto?guid=4959673285448908151" rel="nofollow,noindex">https://www.ibm.com/developerworks/java/jdk/tools/gcmv/</a></p> </td>      </tr>      <tr>       <td>JVM堆和类的元数据的内存泄漏分析</td>       <td> <p>Oracle Java VisualVM and Oracle Java Mission Control</p> <p>IBM Monitoring and Diagnostic Tools for Java</p> <p>Memory Analyzer(heap dump analysis, hprof and phd formats)</p> <p><a href="/misc/goto?guid=4959658457243216435" rel="nofollow,noindex">https://www.eclipse.org/mat/</a></p> <p><a href="/misc/goto?guid=4959673285571519685" rel="nofollow,noindex">https://www.ibm.com/developerworks/java/jdk/tools/memoryanalyzer/</a></p> </td>      </tr>      <tr>       <td>JVM内存分析和堆容量评估</td>       <td> <p>Oracle Java VisualVM andJava Mission Control</p> <p>IBM Monitoring and Diagnostic Tools for Java</p> <p><a href="/misc/goto?guid=4959673285647741034" rel="nofollow,noindex">Java profilers</a> (JProfiler, YourKit)</p> <p><a href="/misc/goto?guid=4959673285734060791" rel="nofollow,noindex">http://en.wikipedia.org/wiki/JProfiler</a></p> <p><a href="/misc/goto?guid=4958191740865646953" rel="nofollow,noindex">http://www.yourkit.com/</a></p> <p>Memory Analyzer(heap dump and application memory footprint analysis)</p> </td>      </tr>      <tr>       <td>JVM和中间件并发故障,如thread lock contention和deadlocks</td>       <td> <p>Oracle Java VisualVM and Oracle Java Mission Control(threads monitoring, thread dump snapshots)</p> <p>jstack, native OS signal such as  <strong>kill -3</strong> (thread dump snapshots)</p> <p><a href="/misc/goto?guid=4959673285848078879" rel="nofollow,noindex">http://www.oracle.com/technetwork/java/javase/tooldescr-136044.html#gblfh</a></p> <p>IBM Monitoring and Diagnostic Tools for Java</p> <p>注意:强烈推荐大家关注如何执行一个JVM线程转储分析的相关知识。</p> </td>      </tr>      <tr>       <td>Java应用程序clock time分析和评测</td>       <td> <p>Oracle Java VisualVM and Oracle Java Mission Control(build-in profiler, sampler and recorder)</p> <p><a href="/misc/goto?guid=4959673285647741034" rel="nofollow,noindex">Java profilers</a> (JProfiler, YourKit)</p> </td>      </tr>      <tr>       <td>Java应用程序和线程CPU burn分析</td>       <td> <p>Oracle Java VisualVM and Oracle Java Mission Control(CPU profiler)</p> <p><a href="/misc/goto?guid=4959673285647741034" rel="nofollow,noindex">Java profilers</a> (JProfiler, YourKit)</p> <p>注意:必要的时候,您还可以依赖JVM线程转储和OS CPU每个线程分析。</p> </td>      </tr>      <tr>       <td>Java IO和remoting contention分析,包括超时管理评估和调整</td>       <td> <p>Oracle Java VisualVM and Oracle Java Mission Control</p> <p>(threads monitoring, thread dump snapshots)</p> <p>jstack, native OS signal such as  <strong>kill -3</strong> (thread dump snapshots)</p> <p>IBM Monitoring and Diagnostic Tools for Java</p> <p>注意:强烈推荐大家关注如何执行一个JVM线程转储分析的相关知识。</p> </td>      </tr>      <tr>       <td>中间件,Java EE容器调整,如线程、JDBC数据源,等等</td>       <td> <p>Oracle Java VisualVM and Oracle Java Mission Control(extra focus on exposed Java EE container runtime MBeans)</p> <p>Java EE containeradministration and  <strong>management console</strong></p> </td>      </tr>     </tbody>    </table>    <p> </p>    <p> </p>    <p>来自: <a href="/misc/goto?guid=4959673285948972070" rel="nofollow">https://www.evget.com/article/2016/5/17/24105.html</a></p>    <p> </p>