由不能使用e.printStackTrace();的规范引起的思考
背景
在代码规范中,有着不要使用e.printStackTrace(),请使用logger记录的规范
为什么会有这样一条呢?因为e.printStackTrace() 会导致锁死!!!
e.printStackTrace() 语句要产生的字符串记录的是堆栈信息
这就会产生下面一种情况:
短时间内大量请求访问此接口 -> 代码本身有问题,很多情况下抛异常 -> e.printStackTrace() 来打印异常到控制台 -> 产生错误堆栈字符串到字符串池内存空间 -> 此内存空间一下子被占满了 -> 开始在此内存空间产出字符串的线程还没完全生产完整,就没空间了 -> 大量线程产出字符串产出到一半,等在这儿(等有内存了继续搞啊)-> 相互等待,等内存,锁死了,整个应用挂掉了。
综上,这就是 e.printStackTrace() 引发的血案。
代替
使用logger来代替记录
但是logger来代替,又有几种方式
logger.error(e.getMessage());
logger.error("发生了错误:"+e);
logger.error("发生了错误:",e);
这三种方式有什么区别呢?
logger.error(e.getMessage());
打印的只有异常的错误信息,如果异常没有抛出错误信息,则显示的就是null
logger.error(“发生了错误:”+e);
打印的是异常的类和异常的错误信息,这个也只比上面多了一个异常的类名
logger.error(“发生了错误:”,e);
推荐使用这种,会完整的将e打印出来
上案列
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Test01.class);
try {
User user = null;
user.setUserName("aaa");
}catch (Exception e){
logger.error(e.getMessage());
logger.error("发生了错误:"+e);
logger.error("发生了错误:",e);
}
}
测试结果
15:23:29.528 [main] ERROR com.qing.security.sys.Test01 - null
15:23:29.530 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:java.lang.NullPointerException
15:23:29.532 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:
java.lang.NullPointerException: null
at com.qing.security.sys.Test01.main(Test01.java:13)
可以明显看出三者的区别,因此,如果需要完整的显示异常信息推荐使用 logger.error(“发生了错误:”,e);
下面在测试一个抛出了异常信息的例子
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Test01.class);
try {
throw new Exception("我是个错误的代码");
}catch (Exception e){
logger.error(e.getMessage());
logger.error("发生了错误:"+e);
logger.error("发生了错误:",e);
}
}
测试结果:
15:25:03.178 [main] ERROR com.qing.security.sys.Test01 - 我是个错误的代码
15:25:03.182 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:java.lang.Exception: 我是个错误的代码
15:25:03.183 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:
java.lang.Exception: 我是个错误的代码
at com.qing.security.sys.Test01.main(Test01.java:11)
最终推荐
如果只是想查看显示的异常信息,使用 logger.error(e.getMessage());
如果想查看完整的异常,请使用 logger.error(“发生了错误:”,e);