解析Java橫死之謎,氣定神閒看花開花落

2020-12-22 51CTO

本文轉載自微信公眾號「小姐姐味道  」,作者小姐姐養的狗 。轉載本文請聯繫小姐姐味道公眾號。

Java進程突然不見了,日誌裡並沒有任何它們的信息,它們就那麼憑空蒸發了。日誌、OOM的一些配置參數,根本就不頂用。

不要驚慌。進程沒有靈魂。一個restart,會讓這些程序活蹦亂跳again。

問題是那些restart也無法解決的問題,還有默默在背後運作的墨菲定律。

是誰殺死了心愛的Java進程?

不要太絕情,在死之前,起碼要讓進程發表一點遺言吧。本小篇將分析幾種常見的Java進程消失之謎,讓你氣定神閒看花開花落。

它們有可能:

  • 被作業系統審判了
  • 執行了上帝函數,被隊友埋坑了
  • 使用了錯誤的啟動方式
  • 日誌系統配置錯誤

1. 被作業系統審判了

以下問題已經不止一個小夥伴遇到了:我的java進程沒了,什麼都沒留下,直接蒸發不見了。

why?是因為太多情,對象太多了麼?

這是趣味性和技巧性非常突出的一個問題。

執行dmesg命令,大概率會看到你的進程崩潰信息躺屍在那裡。

為了能看到發生的時間,我們習慣性加上參數T

  1. dmesg -T 

明顯是作業系統看你的進程不順眼,給Kill了。

這個現象,和Linux的內存管理有關。

由於Linux系統採用的是虛擬內存分配方式,JVM的代碼,庫,堆和棧的使用都會消耗內存,但是申請出來的內存,只要沒真正access過,是不算的,因為沒有真正為之分配物理頁面。

隨著使用內存越用越多。第一層防護牆就是SWAP;當SWAP也用的差不多了,會嘗試釋放cache;當這兩者資源都耗盡,殺手就出現了。oom killer會在系統內存耗盡的情況下跳出來,選擇性的幹掉一些進程以求釋放一點內存。

所以這時候我們的Java進程,是作業系統「主動」終結的,JVM連發表遺言的機會都沒有。這個信息,只能在作業系統日誌裡找。

要解決這種問題,首先不能太貪婪。比如一共8GB的機器,你把整整7.5GB分配給了JVM。當作業系統內存不足,你的JVM就可能成為oom-killer的獵物。

不過,通過下面的命令,可以讓進程避免被審判。

  1. echo -17 > /proc/[PID]/oom_adj 

這是因為,oom_adj文件,就是進程被oom killer殺掉的權重,一般介於 [-17,15]之間。越高的權重,意味著更可能被oom killer選中。

一旦你這麼做,你的Java進程就是特權階層了,可以無視規則。

2. 執行了上帝函數

xjjdog對這個函數的評價是:比你起認識它,還不如你不認識它。

這位函數你不要瞅我。說的就是你,System.exit。

這個函數危險得很,它將強制終止我們的應用,而且什麼都不會留下。你應該掃描你的代碼,確保這樣的邏輯不會存在。

相信我,你並沒有需要用程序判斷來立即結束進程的需求,業務系統尤其沒有。如果有,那大概率是不合理的。除非你把Java當腳本用了。

這個函數,是一個非常高級的埋坑技能,尤其是在Android之類的應用中。應用程式崩潰,你將什麼原因都分析不到,哪怕你做了ShutdownHook。

使用exit函數,一定要心存善意。

當然我們並不是對此束手無策。下面這段代碼,就可以阻止exit的執行,霸道非凡。上帝的那隻手,也給掰回去。

  1. import java.security.Permission; 
  2.  
  3. public class S { 
  4.     private static class ExitTrappedException extends SecurityException { 
  5.     } 
  6.     private static void forbidSystemExitCall() { 
  7.         final SecurityManager securityManager = new SecurityManager() { 
  8.             public void checkPermission(Permission permission) { 
  9.                 if (permission.getName().startsWith("exitVM")) { 
  10.                     throw new ExitTrappedException(); 
  11.                 } 
  12.             } 
  13.         }; 
  14.         System.setSecurityManager(securityManager); 
  15.     } 
  16.     private static void enableSystemExitCall() { 
  17.         System.setSecurityManager(null); 
  18.     } 
  19.     public static void main(String[] args) { 
  20.         forbidSystemExitCall(); 
  21.         try { 
  22.             System.exit(0); 
  23.         }catch (Exception ex){ 
  24.             ex.printStackTrace(); 
  25.         } 
  26.         System.out.println("謝謝xjjjdog, 我依然能夠執行"); 
  27.     } 

如果你用盡千方百計,都找不到異常終止的原因,試試掛上這段代碼吧。有可能是救命的哦。

3. 錯誤的啟動方式

再聊一種最初級最常見還經常發生的一種情況,會造成應用程式的意外死亡:那就是對Java程序錯誤的啟動方式。

很多同學對Linux不是很熟悉,使用XShell登陸之後,調用下面的命令進行啟動。

  1. java com.cn.AA & 

這位同學還算有點意識,在最後使用了&號,以期望進程在後臺運行。但可惜的是,很多情況下,隨著XShell Tab頁的關閉,或者等待超時,後面的Java進程就隨著一塊停止了,很讓人困惑。

正確的啟動方式,就是使用nohup關鍵字,或者阻塞在其他更加長命的進程裡(比如docker)。

  1. nohup java com.cn.AA & 

所以,當你登錄上終端tty的時候,一定要鬧明白當前執行的父進程是誰。你可能是所有接下來要運行的所有進程的祖先哦。

4.日誌配置錯誤

如果上面的原因都不是,那大概率是你的項目裡面日誌框架的配置錯誤了。Java中的日誌框架繁多,配置方式多樣,一不小心,就會踩坑。即使你用的是SpringBoot,也會因為依賴包的問題,造成啟動問題。

日誌配置錯誤+異常情況,當然是什麼都不會留下。

使用下面的命令,可以將依賴樹轉移到log文件裡進行分析。

  1. mvn dependency:tree > dep.log 

如果是SpringBoot項目,是可以給main類加點代碼的。

  1. public static void main(String[] args) { 
  2.   try { 
  3.    SpringApplication.run(LinkpowerDtulockApplication.class, args); 
  4.   } catch (Exception e) { 
  5.    System.out.println(e); 
  6.   } 

這樣有什麼異常情況,就可以早點發現。

End另外,還有一些千奇百怪的原因。比如磁碟滿了,句柄不夠了,這些情況都很隱蔽,需要你精確把控系統的細節。

進程這種靜悄悄的死亡方式,通常會給我們的問題排查帶來更多的困難。

通常,我們在關閉服務的時候,會使用「kill -15」,而不是「kill -9」,以便讓服務在臨死之前喘口氣。但並不總是有效,因為程序壓根就沒有機會發表遺言,有更高級別的存在阻止了它。Java進程橫死,我們只能尋找其他手段。

作者簡介:小姐姐味道 (xjjdog),一個不允許程式設計師走彎路的公眾號。聚焦基礎架構和Linux。十年架構,日百億流量,與你探討高並發世界,給你不一樣的味道。我的個人微信xjjdog0,歡迎添加好友,進一步交流。

【編輯推薦】

【責任編輯:

武曉燕

TEL:(010)68476606】

點讚 0

相關焦點

  • 寵辱不驚,閒看庭前花開花落
    偶爾在小池塘邊跌坐看魚,就這樣眉挑煙火過一生,我也想在牡丹亭裡,看著這花,這花曾讓我驚覺相思不露,原來只因已入骨。這樣的一種感情我不曾體會,我也不太想去體會而已。但你是否會覺得這樣很無趣,你是否也會覺得這樣的日子太容易走到盡頭。但我卻覺得這樣的日子充滿著閒適而已,生活太過繁忙於繁瑣的我們,很難去看到我們停留下的樣子而已。
  • 閒看花開花落,坐看雲捲雲舒
    人生一輩子,度過閒適自在的一生,此生此世,不過是希望這一生能夠閒看花開花落,坐看雲捲雲舒罷了。-END-
  • 花開花落,建水一直在等你
    花開花落,建水一直在等你圖片來源:段苡衡 青衣初見漢服店綜合來源:建水縣融媒體中心古城建水臨安二月天氣暄,滿城靚妝春服妍。花簇旗亭錦圍巷,佛遊人嬉車馬闐。曾何幾時,你不曾好好地觀賞鳳凰花的花開花落,你沒有靜下心來看一本書,品一杯用紫陶壺泡的香茗了?茶香溢出陶壺,沁人沁脾。
  • 如何做到寵辱不驚,看庭前花開花落?
    雖如此,但還是有很多股友不能做到寵辱不驚,閒看庭前花開花落。無非是對自己的持倉情況沒有信心,尤其是市場暴跌的時候甚至讓自己一度懷疑,持有的股票是不是出了問題。比如一位股友就問道我,xxxx暴跌了,是不是財務出問題了。當大勢不好的時候,其實不應該糾結於股票本身的走勢,而應該看到市場大環境的影響。
  • 人生,不問花開花落,只為心靈愉悅
    人們常說:「花開有聲,花落無息,今日花開,明日花落。」人生亦是如此,我們選擇了花開,往後也無法拒絕花落。錦瑟流年,時光匆匆。人生既有花開時的唯美絢爛,也有花落時的孤單落寞。驚羨於花開,感嘆於花落。心境不同,感受也不同。
  • 人生花開花落,皆是一種美感
    花開是一種美,花落也是一種美,花開與花落,只不過是美的方式的不同。在具有陽光心態的人看來,落花紛飛,飄飄揚揚,可謂悠閒自得,賞心悅目!那花落,在婉約派詞人的心中,落花遇流水,滿目悽涼,心情鬱結,愁腸百結可見,不管是賞心悅目的美,還是滿目悽涼的美,都是美的一種。黛玉葬花是一種多愁善感,憐香惜玉,觸景生情的悽美,花落是一種美,她亦是美中的風景。
  • 又一仙俠劇要拍,《月都花落,滄海花開》影視化,誰最適合演洛薇
    在這60餘部作品之中,有一部古裝仙俠類影視劇備受矚目,這部劇叫《月都花落,滄海花開》,而這部劇也是除了《鏡雙城》之外的第二部仙俠劇。  大家都知道,自從胡歌的《仙劍奇俠傳》之後,仙俠劇就比較少,而後來楊冪和趙又廷的《三生三世十裡桃花》火遍大江南北之後,仙俠劇就噴湧而出,今年的《琉璃》也是很火,而這部《月都花落,滄海花開》能否創下經典呢?
  • 花開花落終有時
    戴新閣 /文每當看到花落時,總會有一種悽然的感覺,其實也不必傷感,花開花落是一種自然的現象,世上的每一種植物都會經歷不同階段,成熟、孕育、開花,凋謝、枯萎、死亡,周而復始,代代不息。人生何嘗不是如此?人生如花開花落,有開花時的燦爛,也會有花落時的悽涼。花開時,人們蜂擁而至,讚嘆欣賞,品味芬香,花落時,人們惋然離去,感慨嘆息。春有百花秋有月,夏有涼風冬有雪,看花開花謝,如品味人生百態,雲捲雲舒,潮起潮落,月圓月缺,生死離別,別有一番滋味在心頭。
  • 寂寞空庭春欲晚,閒看飛花聽雨落!
    看那一朵朵白雲,一樹樹花開,一縷縷幽香,一陣清風吹過,沁人心脾,賞心悅目。 風過阡陌,花向陽開,一段相思,一份執念;一寸光陰,一份留戀;一抹嫣然,一縷芬芳。萬花叢中一點雪,我想,在這春色撩人的春天裡,你便是枝頭那抹嬌俏的鮮,是春季最為濃淡相宜的一筆,美麗得令人著迷,純潔得讓人陶醉,駐足在三月的春天裡。我輕輕地與春風擦肩,在陽光靜好的時光裡,與一朵梨花相看兩依依。
  • 《花落花開人世夢——<紅樓夢>裡的詩與詞》:以詩詞切入品紅樓
    《花落花開人世夢——裡的詩與詞》 入江 攝《花落花開人世夢——裡的詩與詞》日前出版,其以詩詞切入解讀賞析《紅樓夢》的獨特方法被學界認為獨到而具價值。《紅樓夢》是一部偉大的小說,解讀《紅樓夢》的各種文本如過江之鯉。《紅樓夢》中的詩詞曲賦是整個小說的有機組成部分,均為塑造人物、推動情節服務。
  • 中小學教師職稱評定新動向:要警惕深圳「紅梅花兒花開花落」!
    實際上,論文抄襲造假在教育界早已是司空見慣,但人們又通常是見怪不怪,因為教師職稱評定有教育教學論文或課題的要求而很多教師在不具備論文或課題的情況下大都選擇了抄而襲之。中小學教師職稱評定弊端確實較多,其中之一就是論文造假之風盛行,雖然經過不斷的調整和完善,論文在職稱評定中的權重越來越小,但始終沒有達到零權重而且對於論文或課題造假抄襲也沒有出臺嚴厲的懲處措施。
  • 寵辱不驚,看庭前花開花落;去留無意,望天上雲捲雲舒
    書中摘錄了大量古籍名句、先哲格言,分享幾則如下:交友須帶三分俠氣,做人要存一點素心;士人有百折不回之真心,才有萬變不窮之妙用;非分之福,無故之獲,非造物之釣餌,即人世之機阱;風斜雨急處,要立得腳定;花濃柳豔處,要著得眼高;路危徑險處,要回得頭早。
  • 我是謎白領祭司之琢鏤鑽花攻略
    我是謎是一款非常燒腦的劇本殺遊戲,白領祭司之琢鏤鑽花密碼答案是什麼?今天小編就為大家帶來了我是謎白領祭司之琢鏤鑽花謎題答案,感興趣的玩家一起來看看吧! 白領祭司之琢鏤鑽花解密過程 1)牆盤密文:
  • 花開是景 花落亦是景 賞析《宿新市徐公店》
    花落(花落下?不是秋天,冬天呀!原來初春的花開最豔,一些花會在暮春十分,初夏來臨時,紛紛揚揚地飄落。很多孩子不懂這些道理,也沒見過花落的場景,可設計ppt課件,感受花開花落的瞬間。比時會生出很多美好的畫面,很多美好的詩句。同時培養學生對美的認識,對美好生活的熱愛和追求。)
  • 「虐到心碎」的QQ空間古風說說:只願君心似我心,定不負相思意
    風華燃盡,多少繁華,終化為指間流沙。 看曲終人散已事過境遷,嘆一世繁華卻抵不過柔情萬千。 這一生真真假假,不過是水裡月霧中花,未看清,已是散落成沙。 一抹情長,兩壇桃花釀,三諾言地老天荒。
  • 念紅塵煙火,看花開花落
    念紅塵煙火,看花開花落。書一頁華章,把生命的色彩刻寫上,人間值得。我想,每個人的一生都是一場人間路過,或肩挑日月,或懷抱星辰,或在鋼筋水泥的堅硬中跋涉,或在炊煙四起的悠然間徜徉。站在時光的渡口,看停靠的每一分每一秒,在冬日的寒風中瑟瑟舒展,等待著春風十裡的拈花一笑。
  • 開,落各一千年,花葉永不相見,奈何橋前可奈何,三生石前定三生
    《全唐詩》唐·無名氏彼岸花開開彼岸,斷腸草愁愁斷腸。奈何橋前可奈何,三生石前定三生。花開彼岸本無岸,魂落忘川猶在川。醉裡不知煙波浩,夢中依稀燈火寒。花葉千年不相見,緣盡緣生舞翩遷。花不解語花頷首,佛渡我心佛空嘆。彼岸花開開彼岸,花開葉落永不見。
  • 如懿傳:蘭因絮果,花開花落自有時
    我少時讀的時候只覺得惋惜,如今卻明白了,花開花落自有時。如懿一直以為曾經的少年郎一直都在身邊,但是一次又一次的被辜負,一次又一次的失望,最後斷髮為祭,給曾經的弘曆和青櫻,原來年少情深也可以走到兩看相厭,如懿溫暖了整個深宮,卻溫暖不了一顆帝王心。現在我也明白了蘭因絮果這一句話,花開花落自有時。
  • 閒看庭前花開,榮辱不驚!
    讓團圓與分離像缺了一輪滿月一樣平常,利弊像花開花落一樣自然。不要在意,不要堅持,讓生活中的各種悲歡離合,就像風一樣,來,不管是涼風還是冷風,帶著自然的微笑歸來,不要拒絕,不要迴避,坦然接受命運的饋贈,讓風后的每一個痕跡都成為生活中不可或缺的經歷。哭和笑,成功和失敗是孿生花。人生是一個笑與淚交織的過程。成功和失敗往往是一線之隔。
  • 花開花落,滿心歡喜,驚豔了時光,溫柔了歲月
    有些人不經意的出現,意外的給你驚喜,你以為他就是你生命中的神,可以拯救心靈乾渴的你,其實你錯了,他只是你人生裡匆匆行走的路客,給你的,你擁有的,正是一種短暫的感覺,等到花開花落,愛情不再那麼苛刻時,你會明白,一個人擁有正常的心態很難得,我們的時間,永遠在經歷中慢慢流失,只有回憶是最永恆的我們錯過了,我曾幻想過天長地久;我也曾幻想過和你手牽手走在黃昏的路上。