柚子快報激活碼778899分享:JVM和GC的工作原理
柚子快報激活碼778899分享:JVM和GC的工作原理
JVM和GC的工作原理
JVM
Java虛擬機:Java 虛擬機(Java virtual machine,JVM)是運行 Java 程序必不可少的機制。JVM實現了Java語言最重要的特征:即平臺無關性。原理:編譯后的 Java 程序指令并不直接在硬件系統的 CPU 上執(zhí)行,而是由 JVM 執(zhí)行。JVM屏蔽了與具體平臺相關的信息,使Java語言編譯程序只需要生成在JVM上運行的目標字節(jié)碼(.class),就可以在多種平臺上不加修改地運行。Java 虛擬機在執(zhí)行字節(jié)碼時,把字節(jié)碼解釋成具體平臺上的機器指令執(zhí)行。因此實現java平臺無關性。它是 Java 程序能在多平臺間進行無縫移植的可靠保證,同時也是 Java 程序的安全檢驗引擎(還進行安全檢查)。
JVM 是 編譯后的 Java 程序(.class文件)和硬件系統之間的接口 ( 編譯后:javac 是收錄于 JDK 中的 Java 語言編譯器。該工具可以將后綴名為. java 的源文件編譯為后綴名為. class 的可以運行于 Java 虛擬機的字節(jié)碼。)
JVM architecture:
JVM = 類加載器 classloader + 執(zhí)行引擎 execution engine + 運行時數據區(qū)域 runtime data area classloader :把硬盤上的class 文件加載到JVM中的運行時數據區(qū)域, 但是它不負責這個類文件能否執(zhí)行,而這個是 執(zhí)行引擎 負責的。
classloader
作用:裝載.class文件 classloader有兩種裝載.class文件的方式(時機): 1. 隱式:運行過程中,碰到new方式生成對象時,隱式調用classLoader到JVM 2. 顯式:通過class.forname()動態(tài)加載
執(zhí)行引擎
作用: 執(zhí)行字節(jié)碼,或者執(zhí)行本地方法
runtime data area
JVM 運行時數據區(qū) (JVM Runtime Area) 其實就是指 JVM 在運行期間,其對JVM內存空間的劃分和分配。JVM在運行時將數據劃分為了6個區(qū)域來存儲。
程序員寫的所有程序都被加載到運行時數據區(qū)域中,不同類別存放在heap, java stack, native method stack, PC register, method area.
下面對各個部分的功能和存儲的內容進行描述:
1、PC程序計數器:一塊較小的內存空間,可以看做是當前線程所執(zhí)行的字節(jié)碼的行號指示器, NAMELY存儲每個線程下一步將執(zhí)行的JVM指令,如該方法為native的,則PC寄存器中不存儲任何信息。Java 的多線程機制離不開程序計數器,每個線程都有一個自己的PC,以便完成不同線程上下文環(huán)境的切換。
2、java虛擬機棧:與 PC 一樣,java 虛擬機棧也是線程私有的。每一個 JVM 線程都有自己的 java 虛擬機棧,這個棧與線程同時創(chuàng)建,它的生命周期與線程相同。虛擬機棧描述的是Java 方法執(zhí)行的內存模型:每個方法被執(zhí)行的時候都會同時創(chuàng)建一個棧幀(Stack Frame)用于存儲局部變量表、操作數棧、動態(tài)鏈接、方法出口等信息。每一個方法被調用直至執(zhí)行完成的過程就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。
3、本地方法棧:與虛擬機棧的作用相似,虛擬機棧為虛擬機執(zhí)行執(zhí)行java方法服務,而本地方法棧則為虛擬機使用到的本地方法服務。
4、Java堆:被所有線程共享的一塊存儲區(qū)域,在虛擬機啟動時創(chuàng)建,它是JVM用來存儲對象實例以及數組值的區(qū)域,可以認為Java中所有通過new創(chuàng)建的對象的內存都在此分配。
Java堆在JVM啟動的時候就被創(chuàng)建,堆中儲存了各種對象,這些對象被自動管理內存系統(Automatic Storage Management System,也即是常說的 “Garbage Collector(垃圾回收器)”)所管理。這些對象無需、也無法顯示地被銷毀。
JVM將Heap分為兩塊:新生代New Generation和舊生代Old Generation
Note:
堆在JVM是所有線程共享的,因此在其上進行對象內存的分配均需要進行加鎖,這也是new開銷比較大的原因。鑒于上面的原因,Sun Hotspot JVM為了提升對象內存分配的效率,對于所創(chuàng)建的線程都會分配一塊獨立的空間,這塊空間又稱為TLABTLAB僅作用于新生代的Eden Space,因此在編寫Java程序時,通常多個小的對象比大的對象分配起來更加高效
5、方法區(qū) 方法區(qū)和堆區(qū)域一樣,是各個線程共享的內存區(qū)域,它用于存儲每一個類的結構信息,例如運行時常量池,成員變量和方法數據,構造函數和普通函數的字節(jié)碼內容,還包括一些在類、實例、接口初始化時用到的特殊方法。當開發(fā)人員在程序中通過Class對象中的getName、isInstance等方法獲取信息時,這些數據都來自方法區(qū)。
方法區(qū)也是全局共享的,在虛擬機啟動時候創(chuàng)建。在一定條件下它也會被GC。這塊區(qū)域對應Permanent Generation 持久代。 XX:PermSize指定大小。
6、運行時常量池 其空間從方法區(qū)中分配,存放的為類中固定的常量信息、方法和域的引用信息。
GC
何為GC? 垃圾回收機制是由垃圾收集器Garbage Collection GC來實現的,GC是后臺的守護進程。它的特別之處是它是一個低優(yōu)先級進程,但是可以根據內存的使用情況動態(tài)的調整他的優(yōu)先級。因此,它是在內存中低到一定限度時才會自動運行,從而實現對內存的回收。這就是垃圾回收的時間不確定的原因。
為何要這樣設計:因為GC也是進程,也要消耗CPU等資源,如果GC執(zhí)行過于頻繁會對java的程序的執(zhí)行產生較大的影響(java解釋器本來就不快),因此JVM的設計者們選著了不定期的gc。
GC有關的是: runtime data area 中的 heap(對象實例會存儲在這里) 和 gabage collector方法。 程序運行期間,所有對象實例存儲在運行時數據區(qū)域的heap中,當一個對象不再被引用(使用),它就需要被收回。在GC過程中,這些不再被使用的對象從heap中收回,這樣就會有空間被循環(huán)利用。 GC為內存中不再使用的對象進行回收,GC中調用回收的方法–收集器garbage collector. 由于GC要消耗一些資源和時間,Java 在對對象的生命周期特征(eden or survivor)進行分析之后,采用了分代的方式進行對象的收集,以縮短GC對應用造成的暫停。
在垃圾回收器回收內存之前,還需要一些清理工作。 因為垃圾回收gc只能回收通過new關鍵字申請的內存(在堆上),但是堆上的內存并不完全是通過new申請分配的。還有一些本地方法(一般是調用的C方法)。這部分“特殊的內存”如果不手動釋放,就會導致內存泄露,gc是無法回收這部分內存的。 所以需要在finalize中用本地方法(native method)如free操作等,再使用gc方法。顯示的GC方法是system.gc()。
垃圾回收技術
引用計數法。簡單但速度很慢。缺陷是:不能處理循環(huán)引用的情況。停止-復制(stop and copy)。效率低,需要的空間大,優(yōu)點,不會產生碎片。標記 - 清除算法 (mark and sweep)。速度較快,占用空間少,標記清除后會產生大量的碎片。
JAVA虛擬機中是如何做的? java的做法很聰明,我們稱之為"自適應"的垃圾回收器,或者是"自適應的、分代的、停止-復制、標記-清掃"式垃圾回收器。它會根據不同的環(huán)境和需要選擇不同的處理方式。
柚子快報激活碼778899分享:JVM和GC的工作原理
推薦鏈接
本文內容根據網絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯系刪除。