Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all articles
Browse latest Browse all 15843

Exception性能问题

$
0
0
  •    1.从Exception往上介绍相关结构、代码

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

    fillInStackTrace函数的声明为

Java代码  
1public  synchronized native  Throwable fillInStackTrace();

    这是个native方法。

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

 

代码  
01Java_java_lang_Throwable_fillInStackTrace(JNIEnv *env, jobject throwable) 
02
03    JVM_FillInStackTrace(env, throwable); 
04    return  throwable; 
05
06   
07JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver)) 
08  JVMWrapper("JVM_FillInStackTrace"); 
09  Handle exception(thread, JNIHandles::resolve_non_null(receiver)); 
10  java_lang_Throwable::fill_in_stack_trace(exception); 
11JVM_END 
12   
13void  java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { 
14  if  (!StackTraceInThrowable) return
15  ResourceMark rm(THREAD); 
16   
17  ………………………………………………. 
18  BacktraceBuilder bt(CHECK); 
19  ……………………………………………… 
20  for  (frame fr = thread->last_frame(); max_depth != total_count;) { 
21    methodOop method = NULL; 
22    int  bci = 0
23  ……………………………………………… 
24    bt.push(method, bci, CHECK); 
25    total_count++; 
26  
27   
28  // Put completed stack trace into throwable object 
29  set_backtrace(throwable(), bt.backtrace()); 
30}

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

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

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

 

代码  
1XXXException extends  Exception { 
2   
3  public  void   synchronized fillInStackTrace(){} 
4   
5  … 
6   
7}

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

  • 2.后记

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



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




Viewing all articles
Browse latest Browse all 15843

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>