java中的exception stack有时候不输出的原因

有时候,我们在看java错误日志时,只看到一个java.lang.NullPointerException,却没有看到错误的栈,原因是启动时候有一项参数可以选择配置:OmitStackTraceInFastThrow

JVM 看不到某些异常的stacktrace问题
在java 1.5的release notes里面可以看到这样一句话:

The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow.

大体的意思就是对于cold build-in exception jvm都会throw 没有stacktrace的exception。从1.5开始提供了一个开关关闭此功能

public class TestCompile {
private static final int count = 1000000;
/**
* @param args
*/
public static void main(String[] args)throws Exception {
int index = count;
while(index -- > 0){
try {
work();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void work(){
String value = null;
value.length();
}
}

编译后使用java -server -XX:-OmitStackTraceInFastThrow TestCompile 运行,发现一直都是类似

java.lang.NullPointerException
at TestCompile.work(TestCompile.java:25)
at TestCompile.main(TestCompile.java:17)

的stacktrace。

换成java -server -XX:+OmitStackTraceInFastThrow TestCompile 运行一段时间后就会出现

java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException
java.lang.NullPointerException

这样的exception,说明stacktrace 该优化已经起作用。-XX:+OmitStackTraceInFastThrow选项在-server情况下默认开启。

这就不难解释为何经常在系统日志中看到很多行的java.lang.NullPointerException 苦于找不到stacktrace而不知道错误出在何处。

遇到这种情况,解决的方法也很简单:既然在一段时间后jvm才会进行重新编译优化,那么该错误在刚开始出现的时候还是会有stacktrace的。所以向前搜索日志,或者将程序重启,观察刚重启时候的log便可以找到错误的stacktrace

最后注意的是,上述优化是针对all "cold" built-in exceptions ,不仅仅是NullPointerException

时间: 2024-08-05 12:13:13

java中的exception stack有时候不输出的原因的相关文章

JAVA中调用CMD命令,并输出执行结果

package com.wzw.util; import java.io.BufferedReader; import java.io.InputStreamReader; public class CmdDemo { public static void main(String[] args) { BufferedReader br = null; try { Process p = Runtime.getRuntime().exec("net user"); br = new Bu

Thinking in java中关于Exception的一道面试题.

今天看到Thinking in Java中一个关于Exception的例子:最后看到有一篇总结的比较好的文章, 这里拿来记录下, 文章地址是:http://blog.csdn.net/salerzhang/article/details/46581457  感谢原作者. 1 class Annoyance extends Exception {} 2 class Sneeze extends Annoyance {} 3 4 class Human { 5 6 public static voi

Java中的Exception

1异常相关概述 1.1 什么是异常 异常就是Java程序在运行过程中出现的错误. 前面接触过的空指针,数组越界,类型转换错误异常等 1.2 Throwable Throwable 类是 Java 语言中所有错误或异常的超类. 只有当对象是此类(或其子类之一)的实例时,才能通过 JVM 或者 throw 语句抛出. 1.3异常的继承体系 -Throwable -Error -Exception -RuntimeException 1.4 JVM默认是如何处理异常的? jvm有一个默认的异常处理机制

Java如何将Exception.printStackTrace()转换为String输出

package com.test1; import java.io.PrintWriter; import java.io.StringWriter; public class T010 { /** * @param args */ public static void main(String[] args) { try { String[] arr = {"111", "222"}; arr[2] = "fff"; } catch (Excep

对于java中变量发生改变,引起的输出结果改变

最近刚学java时,有一个题目: 打印100到200之间所有的素数 第一判断100 第二次判断101....一直到200 旁边有个同学,写了程序后,发现没有输出结果,她就问我为什么?我当时一看,感觉好像没什么 问题啊,但是运行了,就是什么都没输出,我就郁闷了,当时她的代码是这样的: public class Text_SuShu {      /**     * @param args     */    public static void main(String[] args)    {  

Java中使用Log4j记录错误、输出日志

简介: Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程.最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码. 官方站点:http://logging.apache.org/log4j/ Log4j配置: 第一步:

java中Date与DateFormat的格式输出

一.DateFormat java.text.DateFormat 使用 getDateInstance 来获取该国家/地区的标准日期格式.另外还提供了一些其他静态工厂方法.使用 getTimeInstance 可获取该国家/地区的时间格式.使用 getDateTimeInstance 可获取日期和时间格式.可以将不同选项传入这些工厂方法,以控制结果的长度(从 SHORT 到 MEDIUM 到 LONG 再到 FULL).确切的结果取决于语言环境,但是通常: SHORT 完全为数字,如 12.1

java中如何按一定的格式输出时间, 必须给出例子

题目2: 按一定的格式输出时间 (视频下载) (全部书籍) 本章源码 import java.util.*;import java.text.SimpleDateFormat;public class Test {    public static void main(String[] args) {        Date date = new Date();//获取当前日期        SimpleDateFormat df = new SimpleDateFormat("yyyy-MMM

动态布局中RadioGroup的RadioButton有时候不互斥的原因

最近在做一个答题类的模块,有单选.简答.调查问卷等,我是用动态布局的方式生成答题项的,在弄单选的时候遇到一个比较奇葩的问题,在代码中生成RadioGroup和RadioButton的时候,会发现不能互斥,变成多选.通过排查发现,只要每个RadioButton去掉setId的设置就正常了,不过原因还是不明确,继续尝试,发现RadioGroup我也设置了一个Id座位题目标识,调用的是RadioGroup.setId,并且发现,这里设置的ID和后面某个RadioButton设置的Id是一样的...终于