Hadoop記憶體溢位(OOM)分類、引數調優化(程式碼模擬記憶體溢位型別並分析原因)
阿新 • • 發佈:2018-12-31
從Java GC的角度解讀代碼:程式20行new的Person物件會首先會進入年輕代的Eden中(如果對象太大可能直接進入年老代)。在GC之前對象是存在Eden和from中的,進行GC的時候Eden中的對象被拷貝到To這樣一個survive空間(survive(倖存)空間:包括from和to,他們的空間大小是一樣的,又叫s1和s2)中(有一個拷貝演算法),From中的對象(演算法會考慮經過GC倖存的次數)到一定次數(閾值(如果說每次GC之後這個對象依舊在Survive中存在,GC一次他的Age就會加1,默認15就會放到Old Generation。但是實際情況比較復雜,有可能沒有到閾值就從Survive 區域直接到Old Generation區域。在進行GC的時候會對Survive中的對象進行判斷,Survive空間中有一些對象Age是一樣的,也就是經過的GC次數一樣,年齡相同的這樣一批對象的總和大於等於Survive空間一半的話,這組對象就會進入old Generation中,(是一種動態的調整))),會被複制到Old Generation,如果沒到次數From中的對象會被複制到To中,複製完成後To中儲存的是有效的對象,Eden和From中剩下的都是無效的對象,這個時候就把Eden和From中所有的對象清空。在複製的時候Eden中的對象進入To中,To可能已經滿了,這個時候Eden中的對象就會被直接複製到 OldGeneration中,From中的對象也會直接進入Old Generation中。就是存在這樣一種情況,To比較小,第一次複製的時候空間就滿了,直接進入old Generation中。複製完成後,To和From的名字會對調一下,因為Eden和From都是空的,對調後Eden和To都是空的,下次分配就會分配到Eden。一直循環這個流程。好處:使用對象最多和效率最高的就是在Young Generation中,通過From to就避免過於頻繁的產生Full GC(Old Generation滿了一般都會產生FullGC)虛擬機在進行MinorGC(新生代的GC)的時候,會判斷要進入Old Generation 區域對象的大小,是否大於Old Generation剩餘空間大小,如果大於就會發生Full GC。剛分配物件在Eden中,如果空間不足嘗試進行GC,回收空間,如果進行了MinorGC空間依舊不夠就放入Old Generation,如果OldGeneration空間還不夠就OOM了。比較大的對象,數組等,大於某值(可配置)就直接分配到老年代,(避免頻繁記憶體拷貝)年輕代和年老代屬於Heap空間的Permanent Generation(永久代)可以理解成方法區,(它屬於方法區)也有可能發生GC,例如類的實例對象全部被GC了,同時它的類加載器也被GC掉了,這個時候就會觸發永久代中對象的GC。如果OldGeneration滿了就會產生FullGC