对于系统地介绍Java问题定位类的教程少之又少,即使有这方面的内容,往往也是一笔带过。本教程系统地介绍Java问题定位技术,我相信有一些很少公开的定位技术,在正确使用时,可以产生令人惊讶的效果。
采用Java开发的大型应用系统越来越大、越来越复杂;很多系统甚至是将很多第三方系统 集成在一起,整个系统看起来像一个黑盒子。系统运行遭遇问题(系统停止响应,运行越来越 慢,或者性能低下,甚至系统core dump),如何迅速命中问题的根本原因是颇具挑战性的任务。 这类问题的定位技巧是本文介绍的重点,借助这些技巧可以快速找到这些问题的突破口。
功能性的问题定位往往有很清晰的套路(如单步跟踪等),对此不做介绍。着重介绍稳定性和可靠性方面的问题定位技术,特别是那些在实验室难以发现的深层次的问 题。将Java问题定位的方法体系化,提供一种以黑盒子方式进行问题定位的思路:如何使 用线程堆栈进行性能瓶颈分析?如何分析内存泄漏?如何分析系统挂死?在掌握所介绍的方法后,很多情况下无需对系统了解就可以对这类问题进行定位。
对于可靠性和稳定性等非功能需求很多时候难以验证,我们不可能写出"万能的"测试用 例来发现系统所有的可靠性和稳定性问题,所以非功能特性缺陷带来的灾难和难以验证的特 点需要我们采取一切可能的办法进行提前预防,将非功能性需求表现在代码中,是一个优秀 程序工程师的功底的一个体现。因此除了介绍"事后"定位技术以外,同时还介绍了大量 的事前预防技术,对一些严重影响稳定性或者可靠性问题相关的陷阱进行了深入分析,它们正 是大型系统容易忽略但对系统稳定性和可靠性有巨大影响的暗礁,如果能在系统的设计和编 码阶段就防止埋上这些"地雷",那么就不需要事后补救这种代价极高的维护成本。
旨在让软件能表现出"工业强度",即一个"产品级别"的软件,“产品级别"与"功能完 备"是完全不同的两个概念。验收测试的通过与系统能否承受实际应用中的压力完全是两回 事。经过验收测试的系统有可能在真实的环境下表现得一塌糊涂,也有可能非常地棒。举个例 子,我们能保证不存在内存泄漏吗?没人会在测试服务器中在完全模拟实际的负载的情况下 对系统进行一个周或者一个月的测试。因此,通过QA并不能保证没有内存泄漏的发生,因此 它很容易就被带入到产品中。内存泄漏情况大多是与流量相关的,也就是说,流量越大,内存 泄漏的速度就越快。这意味着你根本无法预测什么时候要重启程序,问题往往发生在系统最 忙的时候,墨菲法则往往就在这个时候生效。“产品级别"的另一个方面是系统对所谓"瞬时峰 值"的应对能力,也就是应对系统的短暂性冲击的能力。经过短暂峰值的冲击的系统能否自动 恢复?很多系统经过短暂的峰值冲击,往往不能恢复,这常常是由于异常情况没有很好地进 行"善后处理”,导致大量资源泄漏,比如数据库连接泄露,一旦衰退开始,系统崩溃就只是迟 早的问题了。要想将功能完备软件变为产品级软件,系统要有一套完整的异常处理机制,对异 常进行了合适的"善后处理”,避免由于异常导致的资源泄漏等问题。对这些具有坏味道的代码也进行了深入剖析
介绍的定位技术主要有:内存泄漏定位,线程堆栈分析等。内存定位套路比较固定, 但线程堆栈分析需要一定的火候,它需要一定的悟性和长期的修炼。在可靠性和稳定性问题的定位中,线程堆栈分析是最有力的武器,掌握了这个定位工具,会大大增强自己的"内功"。
对下面一些问题模糊不清的开发人员