消除java異常開銷

拋異常的最大開銷是異常棧的構(gòu)建過程,如果你的程序調(diào)用很深,特別是用了第三方開源框架,這個(gè)開銷是不容忽視的

開銷在哪

查看jdk源碼

    /**
     * Constructs a new throwable with the specified cause and a detail
     * message of {@code (cause==null ? null : cause.toString())} (which
     * typically contains the class and detail message of {@code cause}).
     * This constructor is useful for throwables that are little more than
     * wrappers for other throwables (for example, {@link
     * java.security.PrivilegedActionException}).
     *
     * <p>The {@link #fillInStackTrace()} method is called to initialize
     * the stack trace data in the newly created throwable.
     *
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A {@code null} value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Throwable(Throwable cause) {
        fillInStackTrace();
        detailMessage = (cause==null ? null : cause.toString());
        this.cause = cause;
    }

主要的性能瓶頸在fillInStackTrace,這是一個(gè)native方法.會(huì)構(gòu)建整個(gè)異常棧. 方法簽名如下

/**
     * Fills in the execution stack trace. This method records within this
     * {@code Throwable} object information about the current state of
     * the stack frames for the current thread.
     *
     * <p>If the stack trace of this {@code Throwable} {@linkplain
     * Throwable#Throwable(String, Throwable, boolean, boolean) is not
     * writable}, calling this method has no effect.
     *
     * @return  a reference to this {@code Throwable} instance.
     * @see     java.lang.Throwable#printStackTrace()
     */
    public synchronized Throwable fillInStackTrace() {
        if (stackTrace != null ||
            backtrace != null /* Out of protocol state */ ) {
            fillInStackTrace(0);
            stackTrace = UNASSIGNED_STACK;
        }
        return this;
    }

 private native Throwable fillInStackTrace(int dummy);

如何解決

  1. 創(chuàng)建異常類的時(shí)候重寫fillInStackTrace方法.java7原生支持
protected Throwable(String message, Throwable cause,
                        boolean enableSuppression,
                        boolean writableStackTrace) {
        if (writableStackTrace) {
            fillInStackTrace();
        } else {
            stackTrace = null;
        }
        detailMessage = message;
        this.cause = cause;
        if (!enableSuppression)
            suppressedExceptions = null;
    }
  1. 去掉異常.現(xiàn)在很多業(yè)務(wù)系統(tǒng)用異常實(shí)現(xiàn)程序正常業(yè)務(wù)邏輯.這個(gè)對(duì)性能影響比較大,尤其是并發(fā)比較大的時(shí)候.

尋找異常

有時(shí)候你無法知道那個(gè)異常拋的最多,有些三方包 自己throw Exception 但自己又catch住.

  • brace 跟蹤Exception <init> 對(duì)異常棧,匯總
  • perf top去看下us的開銷,如果_ZN19java_lang_Throwable19fill_in_stack_traceE6HandleP6Thread這個(gè)排名很靠前,那就好好檢查下.

討論

用異常實(shí)現(xiàn)正常的業(yè)務(wù)流程有以下優(yōu)點(diǎn)

  1. 代碼比較精煉.增強(qiáng)代碼可讀性.可以不用對(duì)服務(wù)方法設(shè)計(jì)統(tǒng)一的返回值
  2. 可以使用切面技術(shù)(攔截器 異常處理器) 對(duì)異常做統(tǒng)一的監(jiān)控 和處理.

缺點(diǎn):性能
改進(jìn):

  • 不構(gòu)建異常堆棧,而是保存失敗原因FailCause或者錯(cuò)誤碼
  • 重寫fillInStackTrace方法進(jìn)行noop

參考

知乎上有異常作為業(yè)務(wù)流程控制的討論.請移步
https://www.zhihu.com/question/21405047

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洪碳,一起剝皮案震驚了整個(gè)濱河市兄墅,隨后出現(xiàn)的幾起案子蚊丐,更是在濱河造成了極大的恐慌诈泼,老刑警劉巖常拓,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颈嚼,死亡現(xiàn)場離奇詭異,居然都是意外死亡灾而,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門扳剿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旁趟,“玉大人,你說我怎么就攤上這事∥眩” “怎么了橙困?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長耕餐。 經(jīng)常有香客問我凡傅,道長,這世上最難降的妖魔是什么肠缔? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任夏跷,我火速辦了婚禮,結(jié)果婚禮上明未,老公的妹妹穿的比我還像新娘槽华。我一直安慰自己,他們只是感情好趟妥,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布猫态。 她就那樣靜靜地躺著,像睡著了一般披摄。 火紅的嫁衣襯著肌膚如雪亲雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天疚膊,我揣著相機(jī)與錄音义辕,去河邊找鬼。 笑死酿联,一個(gè)胖子當(dāng)著我的面吹牛终息,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贞让,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼周崭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了喳张?” 一聲冷哼從身側(cè)響起续镇,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎销部,沒想到半個(gè)月后摸航,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舅桩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年酱虎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擂涛。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡读串,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恢暖,我是刑警寧澤排监,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站杰捂,受9級(jí)特大地震影響舆床,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嫁佳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一挨队、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脱拼,春花似錦瞒瘸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赌蔑,卻和暖如春俯在,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娃惯。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工跷乐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趾浅。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓愕提,卻偏偏與公主長得像,于是被迫代替她去往敵國和親皿哨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浅侨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法证膨,內(nèi)部類的語法如输,繼承相關(guān)的語法,異常的語法央勒,線程的語...
    子非魚_t_閱讀 31,581評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理不见,服務(wù)發(fā)現(xiàn),斷路器崔步,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,500評(píng)論 3 93
  • (一)Java部分 1稳吮、列舉出JAVA中6個(gè)比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,071評(píng)論 0 62
  • MD5哈希加密算法 MD5即Message-Digest Algorithm 5(信息-摘要算法 5),用于確保信...
    努力奔跑的____閱讀 1,868評(píng)論 0 1