了解Exception,优化应用性能

4 篇文章 0 订阅
  •    1.从Exception往上介绍相关结构、代码

    class Exception 里面没有什么新鲜东西,它继承自 class Throwable ,接下来我们看一下 Throwable 的结构,在它的构造函数中调用了 fillInStackTrace 这个函数。接下来我们看看这个函数干了些什么。

    fillInStackTrace 函数的声明为

public synchronized native Throwable fillInStackTrace(); 

    这是个 native 方法。

    然后我们到jdk的代码里去找它的具体实现。

 

Java_java_lang_Throwable_fillInStackTrace(JNIEnv *env, jobject throwable)
{
    JVM_FillInStackTrace(env, throwable);
    return throwable;
}

JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver))
  JVMWrapper("JVM_FillInStackTrace");
  Handle exception(thread, JNIHandles::resolve_non_null(receiver));
  java_lang_Throwable::fill_in_stack_trace(exception);
JVM_END

void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) {
  if (!StackTraceInThrowable) return;
  ResourceMark rm(THREAD);

  ……………………………………………….
  BacktraceBuilder bt(CHECK);
  ………………………………………………
  for (frame fr = thread->last_frame(); max_depth != total_count;) {
    methodOop method = NULL;
    int bci = 0;
  ………………………………………………
    bt.push(method, bci, CHECK);
    total_count++;
  }

  // Put completed stack trace into throwable object
  set_backtrace(throwable(), bt.backtrace());
}

    上面的代码中,这一系列调用可以发现,当你 new 一个 exception 的时候, jvm 已经在 exception 里构建好了所有的 stacktrace( BacktraceBuilder bt ,这里花费的代价是可观的,试想一下,在web项目中,调用栈的深度可是很大的。因此,当你对 stacktrace 不感兴趣的时候,不需要这样的信息时,最好不要随便的 new exception

    这里介绍一个常用的避免这种问题的相应的解决方法,即不需要stacktrace信息时,抛自己定义的特殊excepion。

    自定义 XXXException ,覆盖掉 native 的那个函数 , 构造一个空的函数即可,具体实现如下。

 

XXXException extends Exception {

  public void  synchronized fillInStackTrace(){}

  …

}

    然后throw exception的时候,抛自定义的XXXException就好了,这样会大大的提高效率,也节省了空间。

  • 2.后记

    当然做 getStackTrace() 的代价是蛮大的。曾经遇到一个案例,只需要 stacktrace 中的某个 trace ,却要通过 getStackTrace() 这个函数取到所有的 trace ,取其中的第 i 个,这样着实有些不划算。后来我们在 jdk 中给提供了一个接口 StackTraceElement XXXUtils::getStackTraceElement(int index, Throwable t) 便可以达到这个目的,节约了不小的时间开销,也省了内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值