天天下班回家後,相信不少人都是到家後,外衣脫了隨便一扔,鞋脫了踢到一邊,揹包也是隨手一放,鑰匙、錢包、手機也是同樣。其緣由就是咱們要最快的進入回家的狀態--躺下,休息或者作飯,吃東西,看電視總之一切讓本身舒服。無論其餘的,只要達到本身的目的,用計算機的原理來講這叫效率(時間複雜度最低),不接受反駁。算法
可是帶來一個問題就是,時間長了,屋裏必定會很是的亂,地上有不少衣服,日用品,固然還有零食袋等生活垃圾。服務器
若是不清理,在時間長了,垃圾佔用了大量的生活空間,咱們的生活空間愈來愈不夠用了(這就是可以使用的內存變小了---內存泄漏),直到有一天,當咱們下班回到家的時候,腳都放不下了,這個家咱們就回不去了,也就沒法使用了(這就是內存不夠用了---內存溢出OOM)。性能
爲了防止這樣,JVM就有了垃圾回收機制。線程
1.Serial GC ,單線程GC。對象
若是把你的家比做一個堆內存,把你本身比做一個Seriale GC,你會怎麼作呢?內存
若是剛好你的家有兩個屋子,一個客廳,一個臥室。是否是能夠這樣呢:首先,作清理前的準備,先把其中一個屋子(臥室)清理乾淨,平常你只用另外一個屋子(客廳)。等到客廳的很是亂的時候,做爲Seriale GC的你能夠先看下客廳裏那些東西是你想要的(好比,衣服,鞋子,包等)把,這些東西按照類別整理:效率
1.衣服放到你的乾淨的空間(臥室廳),而且疊好,摞在一塊兒;原理
2.鞋子也放到你的乾淨的空間(臥室)拖鞋跟拖鞋放一塊兒,皮鞋跟皮鞋放一塊兒,布鞋跟布鞋放一塊兒,擺放整齊;內存泄漏
3.包包,也是放到臥室,根據其用途,分門別類放整齊;垃圾回收
當把須要的東西,已經區分出來,並放到乾淨的空間(臥室)後,這時候,你就能夠大刀闊斧的清理垃圾了,(拋去須要的,其餘的都是不須要的,不管是零食袋,仍是灰塵等,不用區分,直接一股腦的清理乾淨)由於省去了區分,整理這個步驟,垃圾回收仍是很快的打掃完了,這下,咱們的客廳又是一個乾淨的空間。之後當咱們的臥室,又亂的時候,咱們就能夠以一樣的方式將有用的東西整理到客廳,而後打掃臥室。如此往復,日日月月,開心的過一生……
這就是垃圾回收器的 複製-整理 算法。
可是又有一個問題,複製-整理算法,能知足全部狀況麼?是否能夠經過經過這一招吃遍天下?
固然不會,這種算法只是適合,須要複製-整理的東西比較小部分的時候,當大部分的東西都須要 複製-整理的時候,這個算法就得不償失了。打個比方,當你的客廳比較亂的時候,僅僅是將衣服,鞋子,包包,整理下放到臥室,是否是很容易。若是要是將沙發,茶几,冰箱,彩電,魚缸,等全都要放到臥室裏,而後僅僅是清理下零食袋,以及一小點垃圾那麼,這樣作是否是太傻了。用計算機的術語說,性能浪費嚴重。
那須要清理的東西佔小部分,大部分都是不須要清理的,用什麼辦法呢?
試想一下,這個就是咱們生活中大多數的狀況,由於咱們每次打掃衛生,整理的垃圾都是佔少部分,大部分好比說像是,沙發,茶几,冰箱等家電,都是不須要清理的東西,固然你是國民老公那就例外了。
只須要將少部分垃圾清理,好比說,零食袋,將他放到垃圾袋子裏跟其餘垃圾一併清理出屋子。這就是 標記-清除 算法。找到零食袋放到一邊等着清理(這就是標記),將垃圾一併清理出屋子(這就是清除)。
在咱們JAVA 堆內存裏,新生代Eden,裏大部分對象都是要回收的,因此用 複製-整理 算法;老年的 Old 裏大部分對象是不須要回收的,因此用 標記-清除 算法。
還有一個要注意的是,若是你是Seriale GC,那麼在你收拾屋子的時候,你將沒法 睡覺、洗衣服、作飯,幹其餘的事情,只能一心一意的收拾屋子,直到把屋子收拾完之後才能作其餘的事情。這個事情放到JVM裏就叫作STW(stop the world)。暫停全部的用戶線程,只作垃圾的回收。固然這個對於性能有很大的影響。試想一下,當N多個用戶在秒殺一個東西的時候,這時候你的JVM 在STW,致使服務器一段時間裏屬於不可用狀態。會產生什麼樣的後果,那就不敢想了。