今天再对JVM内存问题分析过程中,对应问题分析和解决方法的一些总结。
不同类型的问题应该形成标准套路
基于我们已有的实践经验,我们应该对不同类型的问题形成标准的解决套路,包括对于问题发现后最基本的问题定义和边界思考。举例来说,对于生产环境如果出现问题,我们首先就是要考虑一个软件运行环境,如果没有做过什么大的变动,一般并不会无缘无故的就出现问题,那么基于这个思路我们思考方式应该为:
1. 环境的基础设施和中间件是否做过变动,比如配置修改,比如各种补丁程序的安装。
2. 对于应用程序本身是否做过新的版本发布
3. 如果上面两个都没有,那么在出现问题的时间段是否出现了大数据量大并发的异常访问。
简单来说上面这个就是最基本的生产环境出现问题的时候思考步骤。比如2和3都没有动过,但是我们对生产环境数据库进行了补丁程序升级,那么出现问题就应该优先假设是补丁程序导致。如果要快速的解决问题,最可行的方法仍然是先对补丁程序进行回滚。
而如果我们从具体出现的问题现象,一步步的去展开追查和分析,往往耗费相当长的时间。
问题的因果要分清
当要给问题出现的时候,你可能会发现多个问题现象,那么这些问题现象里面哪些是因,哪些是果就必须分清楚。因果分析清楚是你开展去寻找问题根源的基础,否则就很容易基于各种问题表象进入到其他误导分支。
比如一个内存溢出和集群故障的问题,这里面就有两个表象,一个是集群节点之间出现了漂移,一个是节点出现了内存溢出问题。那么这里面就有两个因果假设,即:
1. 集群之间的节点迁移,导致出现了内存溢出
2. 内存溢出导致了集群节点的迁移
实际上我们看到上面两个说法都正确,但是我们必须要追查最早的问题根源在哪里?即分析结果为首先是某个节点的内存持续增长到内存溢出,在内存溢出的时候集群管理发现这个问题,将在该节点的运行实例数据迁移到其他的集群节点,但是其他集群节点本身也是堆内存高负荷,因此又导致了更多的集群节点出现内存漂移。
因此最早的因还是在为何集群节点出现了内存溢出,如果没有最早的内存溢出,集群也不会无缘无故的出现集群节点漂移的问题。
非结构化问题解决重点是提出假设并快速验证
要知道对于非结构化的问题解决,重点就是提出假设并快速的进行验证。对于有经验的人和没有经验的人在问题分析解决过程中最大的差异在哪里?
你可以看到最大的差异就在于有经验的会第一次就找到最可能假设并验证确认假设就是问题所在。而对于没有经验的人往往进入到各种非关键问题根源分支,一直绕不出来,而且反而越走越远。所以这里面实际上有两个关键点所在,具体如下:
1. 如果提出最可能假设?
2. 在你提出假设后,如何快速的去验证你的假设。
还是回到生产环境来说,基于前面的分析套路我们已经说到最可能的情况往往是环境有变动,程序有重新部署。但是你会看到对假设的验证复杂度不一样。如果仅仅是程序有部署,往往对程序回退相对容易,但是如果是整个环境基础设施做了大变动,比如一次打了多个修补的补丁,那么这个回滚操作就相对麻烦,而且即使全部回滚问题得到了解决你也会陷入一个窘境,就是不清楚具体是哪个补丁导致的问题。
其次,如果我们假设是程序部署原因导致的问题,在程序部署回退后问题消失,那么基本可以验证我们的假设成立,但是这个时候问题根源还没有彻底找到。我们还得重新Review我们的代码变更,确定究竟是哪里的代码修改导致了内存泄漏和问题的出现。
对于问题标准解决过程中困难不要绕过
在解决问题的过程中我们可能会遇到新问题,但是我想谈的就是对于问题标准解决方法套路中你遇到的问题一定不要去绕过,而是要想方设法的去解决掉你遇到的新问题。
比如对于内存溢出的问题,观察到的现象就是堆内存持续的增长而无法释放,而且在进行full gc的时候内存也无法回收,最终导致内存溢出。而对于这个问题,简单来说即:
内存溢出--》内存泄漏-》应该去分析内存哪里泄漏-》dump内存数据进行分析
上面这个就是对于内存溢出和泄漏最标准的解决模式,我们就需要沿着这个模式走,在这里你不要再去提出各种假设,去猜测究竟哪里出现了内存泄漏。因为dump分析可以最快速的诊断处哪里有内存泄漏,这条路往往才是最佳最高效的解决路径。
因此我们分析过程仍然是jmap dump处内存数据,然后安装Memory Analyse分析工具 MAT进行分析。但是我们在启动MAT并导入dump数据的时候,由于dump数据差不多有6个多g,导致这个数据根本无法装载进来。那么这个时候你务必不要绕过这个问题,而是要去解决新问题。
即MAT如何装载如很大的dump内存数据,或者MAT装载大文件失败如何处理?
即你一定要去解决这个问题,而最终我们调整了MAT启动参数的堆内存大小设置后解决了这个问题,dump文件可以成功装载,在运行分析结果后,我们就可以明显看到究竟是在哪个地方导致的内存溢出或长时间内存占用而无法释放。
原文 http://blog.sina.com.cn/s/blog_493a84550102z7sn.html