51

e.printStackTrace()不是打印吗,还能锁死?

 5 years ago
source link: https://www.tuicool.com/articles/RRna2iV
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

作者:sxgkwei

出处:https://dwz.cn/tQe4fLeD

e.printStackTrace() 会导致锁死?这仅仅是打印啊,怎么可能?

先别惊呼不可能,且听我细细道来。

先看截图1:

QbA3aaU.jpg!web

注意右下角区域,红框部分。这块内存是什么呢?非堆!那么,左边是代码缓存区内存,右边红框就是字符串池,常量,基本类型数据的内存区。然后呢?已经满了。什么原因呢?

e.printStackTrace()

满了的后果呢?整个web服务,访问之后,没响应了,就当是卡死掉了。

再来看截图2:

FRZZ3yr.jpg!web

看看有多少web的请求线程,被卡住在打印这一步!原因呢?要打印字符串输出到控制台上,那你字符串常量池所在的内存块要有空间啊。然而,因为e.printStackTrace() 语句要产生的字符串记录的是堆栈信息,太长太多,内存被填满了!注意 上面代码语句:4208行!

来看图3:

mueyyaq.jpg!web

没毛病,没没事儿找事儿冤枉谁。就是这句代码惹的祸!当然,我承认,被 try 住的代码本身就有问题,导致很多调用都会抛异常。

那么,让我们再来理理整个事件产生的经过:

-> 短时间内大量请求访问此接口 
-> 代码本身有问题,很多情况下抛异常  
-> e.printStackTrace() 来打印异常到控制台 
-> 产生错误堆栈字符串到字符串池内存空间 
-> 此内存空间一下子被占满了 
-> 开始在此内存空间产出字符串的线程还没完全生产完整,就没空间了 
-> 大量线程产出字符串产出到一半,等在这儿(等有内存了继续搞啊)
-> 相互等待,等内存,锁死了,整个应用挂掉了。

总结

总结当然重要,有3点:

1.代码质量啊亲,代码不抛异常咱不就能愉快的继续浪么?

2.不要使用 e.printStackTrace() 啊,这玩意儿,在项目发布后,除过不断的刷控制台,并没用什么卵用啊,您到是用log对象输出到日志文件里面啊。

3.推及开来,在java中,会产生大量字符串的方法,使用时,一定得悠着点,别一不小心撑到肚子(字符串池所属的那么点非堆内存空间),撑到肚子了,会死的啊。

fABVJrv.jpg!web

Ubu2Yvz.gif

BryIFj2.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK