国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

JVM以及垃圾回收器的工作原理

2019-11-08 01:55:06
字體:
來源:轉載
供稿:網友

JVM以及垃圾回收器的工作原理

本文是


執行引擎

作用: 執行字節碼,或者執行本地方法 ### 運行時數據 JVM 運行時數據區 (JVM Runtime Area) 其實就是指 JVM 在運行期間,其對JVM內存空間的劃分和分配。JVM在運行時將數據劃分為了6個區域來存儲。

程序員寫的所有程序都被加載到運行時數據區域中,不同類別存放在heap, java stack, native method stack, PC register, method area.

下面對各個部分的功能和存儲的內容進行描述:

圖片描述

1、PC程序計數器:一塊較小的內存空間,可以看做是當前線程所執行的字節碼的行號指示器, NAMELY存儲每個線程下一步將執行的JVM指令,如該方法為native的,則PC寄存器中不存儲任何信息。Java 的多線程機制離不開程序計數器,每個線程都有一個自己的PC,以便完成不同線程上下文環境的切換。

2、java虛擬機棧:與 PC 一樣,java 虛擬機棧也是線程私有的。每一個 JVM 線程都有自己的 java 虛擬機棧,這個棧與線程同時創建,它的生命周期與線程相同。虛擬機棧描述的是Java 方法執行的內存模型:每個方法被執行的時候都會同時創建一個棧幀(Stack Frame)用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法被調用直至執行完成的過程就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程

3、本地方法棧:與虛擬機棧的作用相似,虛擬機棧為虛擬機執行執行java方法服務,而本地方法棧則為虛擬機使用到的本地方法服務。

4、Java堆:被所有線程共享的一塊存儲區域,在虛擬機啟動時創建,它是JVM用來存儲對象實例以及數組值的區域,可以認為Java中所有通過new創建的對象的內存都在此分配。

Java堆在JVM啟動的時候就被創建,堆中儲存了各種對象,這些對象被自動管理內存系統(Automatic Storage Management System,也即是常說的 “Garbage Collector(垃圾回收器)”)所管理。這些對象無需、也無法顯示地被銷毀。

JVM將Heap分為兩塊:新生代New Generation和舊生代Old Generation

Note: - 堆在JVM是所有線程共享的,因此在其上進行對象內存的分配均需要進行加鎖,這也是new開銷比較大的原因。 - 鑒于上面的原因,Sun Hotspot JVM為了提升對象內存分配的效率,對于所創建的線程都會分配一塊獨立的空間,這塊空間又稱為TLAB - TLAB僅作用于新生代的Eden Space,因此在編寫Java程序時,通常多個小的對象比大的對象分配起來更加高效

5、方法區

方法區和堆區域一樣,是各個線程共享的內存區域,它用于存儲每一個類的結構信息,例如運行時常量池,成員變量和方法數據,構造函數和普通函數的字節碼內容,還包括一些在類、實例、接口初始化時用到的特殊方法。當開發人員在程序中通過Class對象中的getName、isInstance等方法獲取信息時,這些數據都來自方法區。

方法區也是全局共享的,在虛擬機啟動時候創建。在一定條件下它也會被GC。這塊區域對應Permanent Generation 持久代。 XX:PermSize指定大小。

6、運行時常量池 其空間從方法區中分配,存放的為類中固定的常量信息、方法和域的引用信息。


GC

javapapers

Java garbage collection is an automatic PRocess to manage the runtime memory used by programs. By doing it automatic JVM relieves the programmer of the overhead of assigning and freeing up memory resources in a program.

java 與 C語言相比的一個優勢是,可以通過自己的JVM自動分配和回收內存空間。

何為GC?

垃圾回收機制是由垃圾收集器Garbage Collection GC來實現的,GC是后臺的守護進程。它的特別之處是它是一個低優先級進程,但是可以根據內存的使用情況動態的調整他的優先級。因此,它是在內存中低到一定限度時才會自動運行,從而實現對內存的回收。這就是垃圾回收的時間不確定的原因。

為何要這樣設計:因為GC也是進程,也要消耗CPU等資源,如果GC執行過于頻繁會對java的程序的執行產生較大的影響(java解釋器本來就不快),因此JVM的設計者們選著了不定期的gc。

GC有關的是 runtime data area 中的 heap(對象實例會存儲在這里) 和 gabage collector方法。

程序運行期間,所有對象實例存儲在運行時數據區域的heap中,當一個對象不再被引用(使用),它就需要被收回。在GC過程中,這些不再被使用的對象從heap中收回,這樣就會有空間被循環利用。

GC為內存中不再使用的對象進行回收,GC中調用回收的方法收集器garbage collector. 由于GC要消耗一些資源和時間,Java 在對對象的生命周期特征(eden or survivor)進行分析之后,采用了分代的方式進行對象的收集,以縮短GC對應用造成的暫停。

在垃圾回收器回收內存之前,還需要一些清理工作。

因為垃圾回收gc只能回收通過new關鍵字申請的內存(在堆上),但是堆上的內存并不完全是通過new申請分配的。還有一些本地方法(一般是調用的C方法)。這部分“特殊的內存”如果不手動釋放,就會導致內存泄露,gc是無法回收這部分內存的。 所以需要在finalize中用本地方法(native method)如free操作等,再使用gc方法。顯示的GC方法是system.gc()

垃圾回收技術

方法一:引用計數法。簡單但速度很慢。缺陷是:不能處理循環引用的情況。

方法二:停止-復制(stop and copy)。效率低,需要的空間大,優點,不會產生碎片。

方法三:標記 - 清除算法 (mark and sweep)。速度較快,占用空間少,標記清除后會產生大量的碎片。

JAVA虛擬機中是如何做的? java的做法很聰明,我們稱之為自適應的垃圾回收器,或者是自適應的、分代的、停止-復制、標記-清掃式垃圾回收器。它會根據不同的環境和需要選擇不同的處理方式。

heap組成

由于GC需要消耗一些資源和時間的,Java在對對象的生命周期特征進行分析后,采用了分代的方式來進行對象的收集,即按照新生代、舊生代的方式來對對象進行收集,以盡可能的縮短GC對應用造成的暫停. heap 的組成有三區域世代:(可以理解隨著時間,對象實例不斷變換heap中的等級,有點像年級)

新生代 Young Generation 1. Eden Space 任何新進入運行時數據區域的實例都會存放在此 2. S0 Suvivor Space 存在時間較長,經過垃圾回收沒有被清除的實例,就從Eden 搬到了S0 3. S1 Survivor Space 同理,存在時間更長的實例,就從S0 搬到了S1

舊生代 Old Generationtenured 同理,存在時間更長的實例,對象多次回收沒被清除,就從S1 搬到了tenured

Perm 存放運行時數據區的方法區

Java 不同的世代使用不同的 GC 算法。

Minor collection: 新生代 Young Generation 使用將 Eden 還有 Survivor 內的數據利用 semi-space 做復制收集(Copying collection), 并將原本 Survivor 內經過多次垃圾收集仍然存活的對象移動到 Tenured。Major collection 則會進行 Minor collection,Tenured 世代則進行標記壓縮收集。

圖片描述

To note that 這個搬運工作都是GC完成的,這也是garbage collector 的名字來源,而不是叫garbage cleaner. GC負責在heap中搬運實例,以及收回存儲空間。

GC工作原理

JVM 分別對新生代和舊生代采用不同的垃圾回收機制

何為垃圾?

Java中那些不可達的對象就會變成垃圾。那么什么叫做不可達?其實就是沒有辦法再引用到該對象了。主要有以下情況使對象變為垃圾:

1.對非線程的對象來說,所有的活動線程都不能訪問該對象,那么該對象就會變為垃圾。

2.對線程對象來說,滿足上面的條件,且線程未啟動或者已停止。

例如: (1)改變對象的引用,如置為null或者指向其他對象。

  Object x=new Object();object1   Object y=new Object();object2   x=y;object1 變為垃圾   x=y=null;object2 變為垃圾 

(2)超出作用域

if(i==0){ Object x=new Object();object1 }//括號結束后object1將無法被引用,變為垃圾

(3)類嵌套導致未完全釋放

class A{ A a; } A x= new A();//分配一個空間 x.a= new A();//又分配了一個空間 x=null;//將會產生兩個垃圾

(4)線程中的垃圾

class A implements Runnable{ void run(){ …. } } main A x=new A();object1 x.start(); x=null;//等線程執行完后object1才被認定為垃圾 這樣看,確實在代碼執行過程中會產生很多垃圾,不過不用擔心,java可以有效地處理他們。


JVM中將對象的引用分為了四種類型,不同的對象引用類型會造成GC采用不同的方法進行回收: (1)強引用:默認情況下,對象采用的均為強引用 (GC不會回收)

(2)軟引用:軟引用是Java中提供的一種比較適合于緩存場景的應用 (只有在內存不夠用的情況下才會被GC)

(3)弱引用:在GC時一定會被GC回收

(4)虛引用:在GC時一定會被GC回收


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 四平市| 汶上县| 安国市| 天祝| 工布江达县| 宝清县| 孟村| 宝应县| 无锡市| 孟津县| 连江县| 海丰县| 苍梧县| 陇川县| 荥经县| 伊吾县| 康马县| 文昌市| 长泰县| 磐石市| 宜君县| 安平县| 衡山县| 随州市| 中西区| 东海县| 吉隆县| 三江| 武乡县| 章丘市| 禹州市| 莱州市| 柳河县| 澳门| 奉化市| 修武县| 噶尔县| 岑溪市| 星子县| 秦皇岛市| 翼城县|