Java虛擬機之垃圾回收詳解一html
Java技術和JVM(Java虛擬機)java
1、Java技術概述:web
Java是一門編程語言,是一種計算平臺,是SUN公司於1995年首次發佈。它是Java程序的技術基礎,這些程序包括:實用程序、遊戲、商業應用程序。在全世界範圍內,Java運行在超過數十億臺我的計算機上,數十億臺設備上,還包括手機和電視設備。Java由一系列的關鍵組件做爲一個總體構建出了Java平臺。express
Java Runtime Edition編程
當你下載Java,你就獲得了Java運行環境(JRE)。JRE包括Java虛擬機(JVM)、Java平臺核心類文件、支持Java平臺的類庫。對於運行Java程序,這三個部分都是必須的。安全
Java Programming Language網絡
Java是一門面向對象編程語言,具備如下特性:數據結構
JDK是Java程序開發的工具集,你可使用它編譯用Java語言編寫的程序,而後在JVM上運行你編寫的程序。另外,JDK還提供打包和發佈程序功能。多線程
JDK和JRE共享Java程序編程接口(Java API)。Java API 是Java供開發人員編寫Java程序時使用的預打包庫,Java API 提供工具使得Java程序開發更容易,好比字符串操做、日期/時間處理、網絡編程、實現數據結構(例如:鏈表,maps、堆棧、隊列)。架構
JVM是一臺抽象的計算機。JVM是一個程序,這個程序看起來像是一臺計算機,它能夠執行程序。經過這種方式,Java程序的編寫使用了相同的接口和庫。每種JVM對應着特定的操做系統,將Java指令轉換爲能夠在該操做系統上運行的指令或是命令。經過這種方式,Java程序實現了平臺獨立性。
其實JVM對Java語言是一無所知的,JVM能識別的是特殊的二進制格式和類文件格式。一個類文件包含了JVM指令或者字節碼、符號表、以及一些輔助信息。
爲了安全起見,JVM對於類文件中的編碼的語法和結構有嚴格的規定。However, any language with functionality that can be expressed in terms of a valid class file can be hosted by the Java virtual machine. Attracted by a generally available, machine-independent platform, implementors of other languages can turn to the Java virtual machine as a delivery vehicle for their languages.(這幾句話不太理解,暫時放在這裏吧!)
2、探索JVM的結構:
HotSpot JVM 的架構使得它能支持強大的基礎特性和性能,而且可以實現高性能和較好的擴展性。例如,HotSpot JVM JIT編譯器能夠在編譯時進行動態優化。換言之,這些編譯器能夠在Java程序運行時作出最優選擇,生成高性能的本地主機指令以適應本地主機系統架構。另外,它的運行環境和多線程垃圾回收變的愈來愈成熟,愈來愈具備持久的工程性,HotSpot JVM 在大型計算機系統上也表現出可擴展性。
JVM 主要的組件包括:類加載器、運行時數據區、執行引擎。
JVM 跟性能相關的主要組件以下圖中高亮部分。
JVM中有三個組件和性能密切相關。堆是對象數據存儲區,這個區域由垃圾回收管理。大多數調試性能和堆的大小有關,也和選擇合適的垃圾回收器相關。JIT 編譯器對性能影響很大,但不多須要調試新版本的JVM。
垃圾回收概述
什麼是垃圾自動回收?
垃圾自動回收是一個查看堆內存的過程,在此過程當中辨識出那些對象仍在使用,哪些對象再也不使用而後刪除不會再被使用的對象。一個的對象或者對象引用正在使用的意思是程序的某個部分仍然保持着一個指針指向這個對象或對象的引用。一個再也不使用的對象或引用意思是再也不被程序的任何部分所引用。因此未被引用的對象所佔的內存空間是能夠被回收的。
在C語言中,分配和回收內存是用戶手動操做的,在Java語言中,內存回收是由垃圾回收器自動完成的。垃圾回收基本過程:
步驟1:標記
第一步是標記。這個過程是垃圾回收器標記出那片內存在使用,那片不在使用。
藍色表示被引用對象,金色表示未被引用對象。在作出這個標記階段,全部對象都被掃描一遍(如此操做,效率必然很低啊)。若是系統中的全部對象都須要被掃描一遍是一個很耗時的過程。
步驟2:普通刪除
普通刪除是刪除未被引用的對象,保留被引用對象而且使用指針指向刪除後的空閒空間。
內存回收器保存了空閒塊的地址引用來分配給新的對象使用。
步驟2a:壓縮刪除
爲了進一步改善性能,在刪除未被引用對象後,壓縮空間裏剩餘的被引用對象。經過移動被引用對象在一塊兒,使得空閒空間聚合在一塊兒,更便於新的內存分配。
爲何分代垃圾回收?
如以前所述,標記和壓縮JVM中的全部對象是效率很低的。隨着愈來愈多的對象被分配空間,對象鏈表愈來愈大使得垃圾回收時間愈來愈長。然而,根據對程序分析的經驗代表,大多數對象的生命週期很短。
以下圖數據所示,Y軸表明被分配的字節數,X表明隨時間推移被回收的字節數。
如你所見,隨着時間推移保留在內存中的對象愈來愈少。實際上,大多數對象的生命週期都很短,如圖所示,X軸左側有很大的值,短期內巨幅降低。
JVM中的分代
從對象分配的動做中獲得的信息能夠用來改善JVM的性能。所以,堆能夠被分爲更小的塊或是分代。堆可分紅:新生代、老或者是年老代和永久代。
新生代存儲了全部的新建對象。當新生代溢出時,觸發minor garbage collection。在假定對象高死亡率的狀況下,Minor collections 是最優的垃圾回收選擇。一個充滿廢棄對象的新生代內存空間回收很快。某些存留的對象年齡增長而後移動到Old Gerneration。
Stop the World Event - 全部 minor garbage collection 都是 」stop the world「 事件,便是全部的線程都會被中止直到垃圾回收操做完成。
Old Gerneration 用來存儲長時間存活的對象。典型的,JVM會爲新生代設置一個閾值,當新生代年齡達到此閾值,此對象會被移動到old generation。即便old generation 也須要被回收。old generation 被回收事件叫作 major garbage collection 。
major garbage collection 也是 stop the world事件。一般 major garbage collection 會更慢,該過程包括全部的存活對象。因此對於響應式的程序,major garbage collection 須要最小化。一樣須要注意,major garbage collection 所引發的 stop the world事件的時間長度受Old Gerneration空間所採用的垃圾回收器的類別影響。
永久代存儲了元數據,這些元數據是JVM用來描述程序中所使用的類文件和方法的。old Gerneration 存儲了JVM運行時所依賴的類。另外,Java SE 類庫文件和方法也可能存儲在這裏。
類文件也可能被回收,若是JVM發現他們再也不被須要,回收的空間用於存儲哪些程序所必須的類。全部的垃圾回收都會對永久代空間進行收集。
分代垃圾收集過程
既然已經理解了堆分代的緣由,如今來看一下不一樣空間如何相互影響的。下圖描述了JVM中對象分配內存和對象老齡化的過程:
1.首先,任何新對象分配到eden 空間。兩個survivor空間開始時均爲空。
2.當eden 空間溢出時,minor garbage collection 被觸發。
3.被引用的對象被移動到第一個survivor空間。當eden 空間被清空時未被引用的對象被刪除。
4.下一次minor GC時,eden空間執行相同動做。未被引用對象被刪除,被引用對象移動到一個survivor空間。然而,在這種狀況下,被引用對象移動到S1中。另外,由上次minor GC產生的存儲在S0中的對象年齡增長而且移動到S1中。一旦全部存活對象都被移動到S1中,S0和eden空間都被清空。注意到,如今在survivor空間中有不一樣年齡的對象。
5.下一次minor GC時,重複一樣的過程。然而,此次survivor空間互換了。被引用對象移動到了S0。存活對象年齡增長,eden 和 S1 被清空。
6.下面說明的是一次升級過程。在一次minor GC以後,當老年代的對象的年齡達到特定年齡閾(這個例子中閾值是8)時,這些對象重新生代升級成ld generation。
7.隨着minor GC繼續發生,對象繼續被移動到old generation 空間。
8.young generation 通過屢次的minor GC 以後,最終,major GC 會在 old generation 上執行以清理並壓縮此內存空間。
總結:以上就是垃圾回收的基本原理和過程,有錯誤之處請指正!
附:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html