Java最外层异常的抓取要用Throwable

3月 22nd, 2016 2,940 留下评论 阅读评论

3月以来,从来运行正常的link无故崩了好多次,现象:无异常日志,用jstack看主线程挂了进程还在,主线程最外层有catch异常,但是并没有打印日志,实在匪夷所思。

先是怀疑socket连接,通过系统监控看到socket连接数在1w左右,进程ulimit 65536,无内核相关日志。

这时候用jstat分析内存使用,发现link的YGC和FGC增长非常迅速,而且老年代常年在90%以上经常在95%以上,几秒到十几秒一次FGC,一秒2-3次YGC。显然内存已经在崩溃边缘,这时候就想到了可能因为内存不够抛出了OutOfMemoryError,因为是Error,catch Exception无法捕捉!但是在测试机手动模拟抛出OutOfMemoryError,却引发了整个进程的挂掉而不仅仅是主线程。不过这里提供了思路,应该是抛出了某种Error。

无奈对link进行修改重新编译打包(毕竟这个工程从来没有动过,而且非常关键重要,一直不敢改动),将最外层的catch Exception改为catch Throwable,还加上了UncaughtExceptionHandler的实现来捕获主线程可能未捕捉的异常。同时将link的内存从默认值(48g的机器,应该默认为12g)直接加大到24g。运行后一段时间,内存使用情况过度良好,完全没有FGC了,YGC也很少,看来是吓怕了给了太多了内存了。本来以为加大了内存后不会再崩了,坚持了很久之后终于又崩了一次,抓取到了Error找到了原因!

原来是因为热部署修改app时,修改了与link共用的common.jar包后引起的java.lang.NoClassDefFoundError,怪不得了。其实一直就有在怀疑这个在app中会出现的问题,怎么在link中一直没出现过,果然不是偶然啊,虽然在近期才大量爆发之前一直安然无恙也是比较奇怪。引起NoClassDefFoundError的类,与上次部署时修改的一个类处于同一个package下,不知道是不是直接原因。

最外层异常的抓取要用Throwable啊!

至于Java进程运行后替换jar包引起的NoClassDefFoundError问题,值得具体再研究!

Categories: Java 标签:
  1. 还没有评论呢。