為什麼要「除夕」,原來是內存爆了!

2021-02-15 悟空聊架構

傳說古代有一隻四角四足的怪獸:名叫夕。因冬天大雪導致夕沒東西吃,所以夕經常到附近的村裡找吃的,因其身體龐大、脾氣暴躁、兇猛異常,給村民帶來了很大的災難。

後來有一位聰明的孩子,他叫做年,教給大家除掉「夕」的方法:用爆竹,輕則趕走它,重則傷它。每年臘月三十,夕都會來村裡,村名就守著夜,放著鞭炮趕走夕。除夕由此而來。

」我們把「夕」想像成一個不斷吃機器內存的 Java 程序,就稱它為 年獸吧。掌管 Java 虛擬機內存的就是「年」,我們稱它為年哥吧。
年獸的地盤

年哥管理的地盤主要分為五大區:堆、方法區、虛擬機棧、本地方法棧、程序計數器。如下圖所示。另外大家可以把圖中的線程想像成村民,而堆是作為村民共享使用的區域。

運行時數據區

堆又可以進行細分,分為新生代和老年代,新生代和老年代的比例是 1:2,而新生代又可以進行細分,分為伊甸園(Eden)區和兩個 Survivor, 其中 Eden 區大小和 Survivor 區大小是 8:1。

如下圖所示,年獸和村民都是共享堆內存這塊地盤的,管理員年哥是管理堆內存的。其中的數字 1、8、20 分別代表佔用內存的份數。

共享堆區年獸的胃口

年獸的胃口是村民的幾百倍,年獸假扮村民逃過了管理員年哥的檢查,年哥對於這種大胃王都是直接分配到老年代去的,因為大胃王需要連續的內存給它吃,而新生代的碎片比較多不滿足條件。在 Java 的世界中,最典型的大胃王就是大對象:如很長的字符串,或者元素數量很龐大的數組。

如下圖所示,村民分配到新生代吃內存,年獸被直接分配到老年代。

年獸被直接分配到老年代大量年獸入侵

年獸嘗到甜頭後,就開始不斷地呼叫它的親戚朋友,大量年獸被分配到了老年代,直接導致老年代的內存空間不足了,如下圖所示:

大量年獸入侵代碼演示

我們用代碼來演示下年獸入侵:

public class SpringFestivalOOM {
    public static void main(String[] args) {
        // 年獸1/2/3,都佔用 10 MB 內存
        byte[] nianShou1 = new byte[10 * 1024 * 1024];
        byte[] nianShou2 = new byte[10 * 1024 * 1024];
        byte[] nianShou3 = new byte[10 * 1024 * 1024];
    }
}

javac SpringFestivalOOM.java

java -Xms20M -Xmx20M SpringFestivalOOM

因為 3 個年獸佔用的內存 30 MB 大於堆的最大內存 20 MB,所以拋出堆內存溢出異常,如下圖所示:

堆內存溢出異常

這個時候年哥和村民才發現,原來有這麼多年獸佔了我們的地盤,趕快消滅它們!

打走年獸

村民們和年哥湊到一塊,討論了下該如何解決這個問題,究其原因就是年獸太多了,要減少他們呼朋喚友來吃內存。

放到我們的 Java 世界中,就是減少大對象的頻繁創建。

我們程式設計師經常出現本地寫完代碼後沒什麼問題,到線上後就出問題,很可能的原因就是線上環境的數據量大,很容易出現大對象的頻繁創建,比如大型促銷活動時,短時間內需要創建大量訂單數據,而訂單數據又比較複雜,有很多欄位,可能會佔用大量的內存空間,最終導致頻繁觸發垃圾回收,而垃圾回收時又會出現 Stop the world 現象,應用程式的性能就降下來了。

守歲

在除夕晚上,都會進行「守歲」,村民們齊聚一堂吃著年夜飯,一起等待除夕的鐘聲。等到天亮再拜訪親戚鄰居。

而守歲這個過程只能待在家裡,不能做其他事情,所以可以看成是垃圾回收時,其他線程不能工作,也就是 Stop the world 的由來。

如下圖所示,除夕之前,村民可以去其他地方活動,除夕夜就只能待在家裡守歲了,到了第二天早上就可以串門拜年了。

守歲總結

本篇通過除夕的故事來講解 Java 中垃圾回收機制,因故事較為簡單,所以並沒有對垃圾回收算法進行深入講解,本篇只能算作垃圾回收的入門,希望能給大家帶來一定啟發作用,對 JVM 很熟的同學就當學習下除夕的來歷吧~

村民作為小對象使用堆區的新生代,年獸作為大對象直接使用堆區的老年代。除夕當晚,大量年獸入侵老年代,導致堆區內存不足,觸發垃圾回收機制。守歲就是待在家裡守著過新年,而垃圾回收時,又會停止其他線程,也就是 Stop the world。避免代碼中頻繁複制或創建大對象是必須做的事情,以免上線後出現問題。「

悟空在這裡預估大家除夕快樂,新年快樂,2021 心想事成,好事成雙~

加雞腿🍗

相關焦點

  • 為什麼1G內存的蘋果能完爆3GB內存的安卓機?
    那麼問題來了,為什麼蘋果1GB內存能完爆3GB內存的安卓手機?而且這一點是安卓無論怎麼抄襲,怎麼優化都無法趕得上蘋果的。至於為什麼,且聽小編慢慢道來。當然1GB內存的機子也有,不過大多都用在主打低端市場的千元機。什麼?512MB內存也能用,不信你同時打開QQ、微信和淘寶,小編保證你的手機卡成狗。二、蘋果1G內存為何能完爆3G的安卓?安卓系統內存的需求變得越來越大之外,這些年呈現出井噴的趨勢。
  • 中國人的除夕習俗與禁忌
    年的最後一天叫「歲除」,那天晚上叫「除夕」。除夕人們往往通宵不眠,叫守歲。」除夕這一天,家裡家外不但要打掃得乾乾淨淨,還要貼門神、貼春聯、貼年畫、掛燈籠。 年夜飯爆竹是中國特產,亦稱「爆仗」、「炮仗」、「鞭炮」。其起源很早,至今已有兩千多年的歷史。放爆竹可以創造出喜慶熱鬧的氣氛,是節日的一種娛樂活動,可以給人們帶來歡愉和吉利。年祭祖
  • 怎麼沒有除夕?除夕29多少年一次?
    一、2022年為什麼沒有大年三十?在2022年公曆1月份的日曆上,1月31日(星期一)是辛丑年臘月廿九,而2月1日卻已經是壬寅年正月初一(也就是春節),這讓一部分人群表示十分的困惑。除夕一般不都是大年三十嘛,2021年農曆最後一天怎麼突然消失了。
  • 2021年除夕竟不是大年三十?
    今日突然有這麼一條消息衝上熱搜瞬間擊碎了眾多人的「三觀」原來除夕可以不是大年三十從日曆來看,1月30日是二十八,31日是除夕,大年三十跑哪兒了呢?       天文專家介紹,這主要與「朔望月」有關,月亮圓缺變化一周稱為一個朔望月,一個周期平均為29.5天。恰逢2022年臘月是小月,便沒有了年三十。專家表示,只要正月初一還在,前一晚都是除夕。       專家稱,從「朔月」到「望月」再回到「朔月」,一個周期平均為29.5天。
  • 2019,立春邂逅了除夕,這些習俗和禁忌你必須要知道!
    2019年的立春與除夕同一天,那麼大家知道除夕日立春多少年一遇嗎?,都是除夕當天逢「立春」。 民間認為,立春與除夕在同一天是很好的,因為立春是一年中第一個節氣,除夕是一年中最後一天,二者在同一天,猶如陰陽太極,道生一,一生二,二生三,三生萬物,更加體現了自然循環的規律。
  • 有關除夕的傳說故事
    老百姓對它恨得要死,但又沒有辦法。  有個叫七郎的獵人,力大無窮,箭射得特別好,餵的狗也非常厲害,任何猛獸都敢去鬥。七郎見百姓被「夕」害苦了,就想除掉他。他帶著狗到處找「夕」,找來找去始終沒有找到。原來「夕」白天不出來,太陽落山後它才出來害人,半夜後又不見了,也沒人曉得它住在哪兒。
  • 2021除夕祝福語大全 除夕快樂的圖片表情
    福盈門,人逢盛世抖精神,享受平安健康身;財神到,愁雲散盡煩惱消,財源滾滾似浪潮;美今宵,除夕團圓人安樂,幸福開心樂逍遙。願你快樂除夕,幸福一生!除夕溫馨蒸年糕,祈願幸福年年高;除夕溫暖掛紅燈,祈願日子火火紅。溫馨溫暖除夕,祝福朋友合家團圓、幸福吉祥、開心快樂、盡享天倫!
  • iPhone很卡但為什麼不能擴展內存, 真相原來是這樣!
    那麼有沒有這樣一種可能,給iPhone擴展內存(RAM)就不會卡了?事實上,iPhone是可以擴展存儲容量(ROM)的,比如將64GB升成128GB或256GB,如果你找數碼維修商家,他們一般會將原來的晶片拆下來,然後換成大容量晶片,比如東芝或者閃迪。
  • 除夕:雙魚玉佩
    《除夕:雙魚玉佩》非VR版上架Steam 5月21日發售 萬歲遊戲開發的國產恐怖遊戲《除夕:雙魚玉佩》非 VR 版現已在 Steam 平臺正式登陸,根據商店頁面的信息顯示本作將於5月21日正式發售,具體售價的等信息還尚未公開
  • 除夕,中國人的年味兒!
    除夕守歲,祈求平安吉祥。也惜別逝去歲月的留戀,迎接新一年的美好到來。晉代官吏周處《風土記》中記載:「除夕,達旦不眠,謂之『守歲』」4《除夜有懷》唐·孟浩然五更鐘漏欲相催,四氣推遷往復回。10《除夕》清·趙翼燭影搖紅焰尚明,寒深知己積瓊英。老夫冒冷披衣起,要聽雄雞第一聲。守歲達旦之時,心裡萌動一股活力,明年要與時俱進,創造人生的新輝煌!
  • 為什麼手機總提示「內存不足」?原來都是它們惹的禍,趕緊清理了
    非常簡單,6代表的是內存,128代表的是存儲。可能有些朋友會覺得不太明白,我們用電腦舉例子,現如今咱們的電腦內存一般是8g或者16g的,但是我們用來存儲的硬碟卻往往達到500G甚至是1T。內存和硬碟的區別,有點類似手機的6+128。這麼說大家能夠明白一些了吧。那麼,為什麼手機總提示「內存不足」?原來都是它們惹的禍,趕緊清理了。
  • 2021年除夕回家日子哪天好 關於除夕的習俗
    我們對於除夕是非常注重的,因為的話對於我們而言除夕就是一個迎接好運氣的重要日子,所以為了這樣子的重要日子的話,我們的話是要做豐盛晚餐還有各式各樣的活動來迎接這天的到來的
  • 跟隨古人過​除夕
    或者掃描下方二維碼關注我們 為天地立心,為生民立命,為往聖繼絕學,為萬世開太平按中國農曆,一年的最後一天謂「除夕」。晉代官吏周處《風土記》中即有「除夕,達旦不眠,謂之『守歲』」的記載。《除夕》清·趙翼燭影搖紅焰尚明,寒深知己積瓊英。老夫冒冷披衣起,要聽雄雞第一聲。
  • 解密:除夕是農曆幾月幾日 除夕吃什麼
    本文部分文字與圖片資源來自於網絡,轉載此文是出於傳遞更多信息之目的,若有來源標註錯誤或侵犯了您的合法權益,請立即後臺留言通知我們,情況屬實,我們會第一時間予以刪除,並同時向您表示歉意在中國傳統文化傳承的過程之中,存在著農曆和陽曆的分別,這也就成為時間方面得益者區別存在,那麼在每年除夕到來的時候
  • 除夕!迎牛年!
    不知不覺,又是一年除夕。除夕除夕,意味著舊的一歲至此夕而除,新的一年至此夕而至。今夜除夕,借這個辭舊迎新的時間交界點,願你我除舊布新。卸下一年的疲憊,丟棄過往所有的不如意,刪除堆積在心底的一切負能量。感受濃鬱的年味,享受幸福美滿,祈願新年吉祥。
  • 除夕快樂,牛年好運來!2021牛年除夕春節朋友圈祝福語,牛年吉祥
    除夕轉瞬到眼前,提早給你拜個年,祝你風風火火開心年,順順利利如意年!打開手機翻一翻,大年三十剩一天。親朋好友送祝福,今年我要送新鮮,首先送你三個有:有吃有喝有朋友;接著送你三個無:無病無怨無憂愁;再送給你三個情:親情愛情和友情;特別送你三個多:錢多物多福氣多!提前給您拜年了。
  • 大年三十除夕最新動態表情祝福圖片,2019春節除夕拜年祝福語
    2、除夕除夕,除去煩惱,除去黴運,迎接美好希望;守歲守歲,守住健康,守住平安,祈禱幸福一生;迎新迎新,迎來快樂,迎來生意隆興。祝2019除夕夜吉祥快樂!7、除夕到,放鞭炮,家家戶戶好熱鬧;舞龍燈,踩高蹺,合家歡樂步步高!眼看大年初一快來到,人人開心齊歡笑,提前祝你春節好,豬年祝福我最早!
  • 2021除夕怎麼發朋友圈,適合除夕零點發的說說句子
    你要忍,忍到春暖花開;你要走,走到燈火通明;你要看過世界遼闊,再評判是好是壞;你要卯足勁變好,再旗鼓相當站在不敢想像的人身邊;你要變成想像中的樣子,這件事,一步都不能讓。你要做一個不動聲色的大人了。不準情緒化,不準偷偷想念,不準回頭看。去過自己另外的生活。你要聽話,不是所有的魚都會生活在同一片海裡。
  • 除夕是幾月幾號?除夕二十九多少年一次?
    除夕29多少年一次?這其實並沒有規定的,畢竟按照往年在我國農曆臘月天數不確定,有的年份為二十九天,有的年份為三十天,因此有的年份沒有臘月三十,臘月二十九就為除夕。而除夕是29號的年份也是不固定的,我們不能按照規律推斷。除夕是舊終,是日終、月終、年終;春節新始,是日始、月始、年始。除夕前要打掃,去舊布新,要守歲,要以好面貌接迎新年。
  • 為什麼電腦都是8G/16G/32G的內存,64G的內存辦公是什麼體驗?
    NO.1 網友:簡大山(程式設計師)工作原因我還真需要64G內存。我是做行業軟體開發的,經常需要在本地電腦同時跑幾個大型應用,32G的電腦跑起來就滿了,卡的要命,必須要64G才能正常工作。NO.2 網友:玩家翁偉(開發)我的PC原來是32G內存,平時用著還行,然後有一天我需要跑:OpenShift WSL + 若干Docker環境+若干IDEOracle,然後,我的電腦內存佔用就變成:然後,我就果斷加了兩條內存變成64G: 系統才恢復能用的狀態,體驗就是可以繼續工作了。