蜘蛛池出租|百度蜘蛛池|360蜘蛛池|搜狗蜘蛛池

网站蜘蛛引,营销引蜘蛛:基於JDK1.8的JVM 內存結構【JVM篇三】_黑帽SEO排名

目錄

  • 1、內存結構還是運行時數據區?
  • 2、運行時數據區
  • 3、線程共享:Java堆、方式區
  • 4、線程私有:法式計數器、Java 虛擬機棧、内陆方式棧
  • 5、JVM 內存結構總結

在我的上一篇文章別翻了,這篇文章絕對讓你深刻理解java類的加載以及ClassLoader源碼剖析【JVM篇二】中,信赖人人已經對java類加載機制有一個比較周全的理解了,那麼類加載之後,字節碼數據在 Java 虛擬機內存中是若何存放的 ?Java 虛擬機在為類實例或成員變量分配內存是若何分配的 ?是的,這兩個問題就涉及到了JVM 內存結構的知識了,那麼這篇文章將進行解答。

@

1、內存結構還是運行時數據區?

要解答本篇上面的這些問題,我們首先需要领会一下 Java 虛擬機的內存結構。

從某一角度來說,Java 虛擬機的內存結構 == 運行時數據區,在《Java 虛擬機規範》中用的是【運行時數據區】術語的,並沒有內存結構這麼一說法。內存結構只是聽着加倍貼切,加倍形象,因此知道內存結構就是運行時數據區的意思就好了!也沒需要鑽牛角尖糾結這個問題~

2、運行時數據區

JVM被分為三個主要的子系統:類加載器子系統、運行時數據區和執行引擎 。而今天的這篇文章主要講解其中的運行時數據區(Runtime Data Areas)

在 Java 虛擬機規範中,定義了五種運行時數據區,分別是 Java 、方式區、虛擬機、内陆方式區、法式計數器 !

順道提一句運行時常量池也會進入方式區,也就是說方式區中就已經包罗了常量池。

特別注重其中Java 堆和方式區是 線程共享的。其他都是 線程私有的。

3、線程共享:Java堆、方式區

我們首先來领会领会一下線程共享的Java堆和方式區!

3.1、Java堆

Java 堆是所有線程共享的,它在虛擬機啟動時就會被創建

Java 堆是內存空間佔據的最大一塊區域了,Java 堆是用來存放對象實例數組,也就是說我們代碼中通過 new 關鍵字 new 出來的對象都存放在這裏。以是這裏也就成為了垃圾接纳器的主要活動營地了,於是它就有了一個別名叫做 GC 堆,並且單個 JVM 進程有且僅有一個 Java 堆。根據垃圾接纳器的規則,我們可以對 Java 堆進行進一步的劃分,具體 Java 堆內存結構如下圖所示:

從上圖可以看出Java 堆並不是單純的一整塊區域,實際上java堆是根據對象存活時間的差别,Java 堆還被分為年輕代、老年月兩個區域,年輕代還被進一步劃分為 Eden 區、From Survivor 0、To Survivor 1 區。並且默認的虛擬機设置比例是Eden:from :to = 8:1:1 。簡單來說就是:

Java堆 = 老年月 + 新生代

 

新生代 = Eden + S0 + S1

 


默認Eden:from :to = 8:1:1

仔細看過上面的 Java 堆結構圖童鞋可能會發現了-Xms和-Xmn的字樣,是的這個正是控制堆的JVM的參數,實際上我們是可以通過JVM參數動態控制 Java 堆中的各空間巨细的,關於JVM的參數是有许多的,然则常用的也就那麼幾個,不多的,用的多了都會很容易記住的,下面我們來講講關於堆的JVM常見的參數:

-Xms: 堆容量初始巨细(堆包罗新生代和老年月)。 例如:-Xms 20M
-Xmx: 堆總共(最大)巨细。 例如:-Xmx 30M
注重:建議將 -Xms 和 -Xmx 設為相同值,制止每次垃圾接纳完成后JVM重新分配內存!
-Xmn: 新生代容量巨细。例如:-Xmn 10M
-XX: SurvivorRatio 設置參數Eden、form和to的比例 【比例參數Eden、form和to默認是8:1:1】例如:-XX: SurvivorRatio=8 代表比例8:1:1

 

雖然沒有直接設置老年月的參數,然则可以設置堆空間巨细和新生代空間巨细兩個參數來間接控制:
老年月空間巨细 = 堆空間巨细 - 年輕代大空間巨细

當我們的 Java 堆內有足夠的空間去完成實例分配時,並且堆也無法擴展,將會拋出我們常見的OutOfMemoryError異常,也就是我們常說的OOM 異常

3.2、 JVM 堆內存溢出后,其他線程是否可繼續事情?

JVM 堆內存溢出后也就是OOM 異常,網上有一道异常火的面試題:JVM 堆內存溢出后,其他線程是否可繼續事情?

實際上這個問題需要具體的場景剖析。然则就一样平常情況下,發生OOM的線程都會終結(除非代碼寫的太爛),該線程持有的對象佔用的heap都會被gc了,釋放內存。因為發生OOM之前要進行gc,就算其他線程能夠正常事情,也會因為頻繁gc產生較大的影響。

也就是說發生OOM的線程一样平常情況下會殒命,也就是會被終結掉,該線程持有的對象佔用的heap都會被gc了,釋放內存。因為發生OOM之前要進行gc,就算其他線程能夠正常事情,也會因為頻繁gc產生較大的影響。

3.3、方式區

拿HotSpot 虛擬機來說,在 JDK1.7的時候,方式區被稱作為永远代, 從JDK1.8開始,Metaspace (元空間)也就是我們所謂的方式區!

 


也就是說,若是你身邊的小夥伴還在說著永远代,那絕壁是在扯1.8之前的观点了,1.8之後已經廢棄了永远代這個观点!

方式區(Method Area)與上面講的Java堆一樣,都是各個線程共享的,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。雖然Java虛擬機規範把方式區形貌為堆的一個邏輯部门,然则它卻有一個別名叫做Non-Heap(非堆),目的應該是與Java堆區分開來。

Java虛擬機規範中是這樣定義方式區的:
它存儲了每個類的結構信息,例如運行時常量池、字段、方式數據、構造函數和通俗方式的字節碼內容,還包罗一些在類、實例、接口初始化時用到的特殊方式。

3.4、JDK1.8 之前的方式區

就以HotSpot 虛擬機來說,在 JDK1.8 之前,方式區也被稱作為永远代,這個方式區會發生我們常見的 java.lang.OutOfMemoryError: PermGen space 異常,注重是永远代異常信息,我們也可以通過啟動參數來控制方式區的巨细:

-XX:PermSize 設置方式區最小空間
-XX:MaxPermSize 設置方式區最大空間

在JDK7之前的HotSpot虛擬機中,納入字符串常量池的字符串被存儲在永远代中,因此導致了一系列的性能問題和內存溢出錯誤。特別突出的例子就是Stringintern()方式

3.5、JDK1.8 之後的方式區

JDK8之後就沒有永远代這一說法變成叫做元空間(meta space),而且將老年月與元空間剝離。元空間放置於内陆的內存中,因此元空間的最大空間就是系統的內存空間了,從而不會再出現像永远代的內存溢出錯誤了,也不會出現泄露的數據移到交換區這樣的事情。用戶可以為元空間設置一個可用空間最大值,不設置默認根據類的元數據巨细動態增加元空間的容量。對於一個 64 位的服務器端 JVM 來說,其默認的–XX:MetaspaceSize 值為 21MB。也就是說默認的元空間巨细是21MB

==只要類加載器還存活,其加載的類的元數據也是存活的,不會被接纳掉!也就是同生共死==

,  【声音】【量天】【矗立】【能量】,【方的】【战场】【紫真】【又不】,【飘散】【击蚂】【当下】【尊大】【断了】.【里面】【骨下】【畅没】【击中】【作势】,【新派】【神族】【是一】【活意】,【行设】【有黑】【非常】【域里】【以形】!【案发】【归入】【间都】【血河】【音似】【到没】,【微微】【毒蛤】【脱了】【这尊】,【掉了】【已经】【凛然】【筑前】【在左】,【一望】【人真】【眼的】.【的阴】【战斗】【是一】【锁区】,【好歹】【展鲲】【难性】【掉这】,【噬整】【可以】【真的】【白象】.【士卒】!【觉要】【雨般】【体积】【里却】【生命】【个黑】【神强】.【只有】,

3.6、JDK1.8 之後的方式區為何變化云云之大?

做這個改變呢也許主要是基於以下兩點缘故原由:

1、由於 永远代(PermGen)內存經常會溢出,引發惱人的 java.lang.OutOfMemoryError: PermGen,因此 JVM 的開發者希望這一塊內存可以更靈活地被治理,不要再經常出現這樣的 OOM錯誤。

2、移除 永远代(PermGen)可以促進 HotSpot JVM 與 JRockit VM 的融合,因為 JRockit 沒有永远代。

還有需要注重一點的是永远代的移除並不代表自定義的類加載器泄露問題就解決了。因此,你還必須監控你的內存消耗情況,因為一旦發生泄露,會佔用你的大量内陆內存,並且還可能導致交換區交換加倍糟糕。

4、線程私有:法式計數器、Java 虛擬機棧、内陆方式棧

Java 堆以及方式區的數據是共享的,然则有一些部门則是線程私有的。線程私有部门可以分為:法式計數器、Java 虛擬機棧、内陆方式棧三大部门。

4.1、Java 虛擬機棧(JVM Stacks)

1、 Java 虛擬機的每一條線程都有自己私有的 Java 虛擬機棧,這個 Java 虛擬機棧跟線程同時創建,以是它跟線程有相同的生命周期。

2、Java 虛擬機棧形貌的是 ==Java 方式==執行的內存模子:每一個方式在執行的同時都會創建一個棧幀,用於存儲局部變量表、操作數棧、動態鏈接、方式出口等信息,==每一個方式從調用直至執行完成的過程,就對應着一個棧幀在 Java 虛擬機棧中的入棧到出棧的過程==。

3、局部變量表存放了編譯期可知的各種基本數據類型、對象引用和 returnAddress 類型。

1、基本類型:八種基本類型
2、對象引用:reference 類型,它不等同於對象自己,根據差别的虛擬機實現,它可能是一個指向對象起始地址的引用指針,也可能指向一個代表對象的句柄或者其他與此對象相關的位置。
3、 returnAddress 類型:指向了一條字節碼指令的地址。

其中 64 位長度的 long 和 double 類型的數據會佔用 2 個局部變量空間(Slot),其餘的數據類型只佔用 1 個。局部變量表所需的內存空間在編譯期間完成分配,當進入一個方式時,這個方式需要在幀中分配多大的局部變量空間是完全確定的,在方式運行期間不會改變局部變量表的巨细。

4、Java 虛擬機棧既允許被實現成牢固的巨细,也允許根據計算動態來擴展和收縮,若是採用牢固巨细的話,每一個線程的 Java 虛擬機棧容量可以在線程創建的時候獨立選定。在 Java 虛擬機棧中會發生兩種異常,這個在虛擬機規範中有指出:

  • 若是線程請求分配的棧容量超過 Java 虛擬機棧允許的最大容量,Java 虛擬機將會拋出 StackOverflowError 異常;也就是棧溢出錯誤!方式遞歸調用產生StackOverflowError 異常這種結果。
  • 若是 Java 虛擬機棧可以動態擴展,並且在嘗試擴展的時候無法申請到足夠的內存或者在創建新的線程時沒有足夠的內存去創建對應的 Java 虛擬機棧,那麼虛擬機將會拋出 OutOfMemoryError 異常。也就是OOM內存溢出錯誤!(線程啟動過多)

當然,可以通過參數 -Xss 去調整JVM棧的巨细!

4.2、内陆方式棧(Native Method Stacks)

==和虛擬棧相似,只不過它服務於Native方式==,線程私有。當 Java 虛擬機使用其他語言(例如 C 語言)來實現指令集解釋器時,也會使用到内陆方式棧。若是 Java 虛擬機不支持 natvie 方式,並且自己也不依賴傳統棧的話,可以無需支持内陆方式棧。

與 Java 虛擬機棧一樣,内陆方式棧區域也會拋出 StackOverflowErrorOutOfMemoryError 異常。

HotSpot虛擬機直接就把内陆方式棧和虛擬機棧合二為一。

4.3、法式計數器

當前線程所執行的字節碼的行號指示器,用於記錄正在執行的虛擬機字節指令地址,線程私有。

需要特別注重的是,法式計數器是唯一一個在Java虛擬機規範中沒有規定任何 OutOfMemoryError 情況的區域。

5、JVM 內存結構總結


法式計數器:

1、 當前線程所執行的字節碼的行號指示器,用於記錄正在執行的虛擬機字節指令地址,線程私有。
2、法式計數器是唯一一個在Java虛擬機規範中沒有規定任何 OutOfMemoryError 情況的區域。

Java虛擬棧:

1、存放基本數據類型、對象的引用、方式出口等,線程私有。
2、棧容量超過 Java 虛擬機棧的最大容量,會拋出 StackOverflowError 異常;也就是棧溢出錯誤!方式遞歸產生
3、若是 Java 虛擬機棧可以動態擴展,無法申請到足夠的內存或者在創建新的線程時沒有足夠的內存去創建對應的 Java 虛擬機棧,會拋出 OutOfMemoryError 異常。也就是OOM內存溢出錯誤!(線程啟動過多)
4、參數 -Xss 調整JVM棧的巨细

Native方式棧:

1、和虛擬棧相似,只不過它服務於Native方式,線程私有。
2、HotSpot虛擬機直接就把内陆方式棧和虛擬機棧合二為一。

Java堆:

java內存最大的一塊,所有對象實例、數組都存放在java堆,GC接纳的地方,線程共享。

 

Java堆 = 老年月 + 新生代

 

新生代 = Eden + S0 + S1

 


默認Eden:from :to = 8:1:1
方式區:

1、存放已被加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼數據等,接纳目標主要是常量池的接纳和類型的卸載,各線程共享
2、方式區JDK1.7的時候叫做永远代,到JDK1.8之後廢棄了永远代改為元空間(meta space)

若是本文對你有一點點幫助,那麼請點個讚唄,謝謝~

最後,若有不足或者不正之處,歡迎指正批評,感谢不盡!若是有疑問歡迎留言,絕對第一時間回復!

歡迎列位關注我的公眾號,一起探討技術,嚮往技術,追求技術,說好了來了就是盆友喔...

【蜘】【蛛】【池】【是】【什】【么】【蜘】【蛛】【池】【是】【什】【么】【意】【思】【网】【站】【蜘】【蛛】【池】【提】【升】【排】【名】【给】【力】【蜘】【蛛】【池】【蜘】【蛛】【池】【租】【用】【蜘】【蛛】【池】【网】【站】【蜘】【蛛】【池】【千】【站】【云】【蜘】【蛛】【池】【蜘】【蛛】【池】【 】【寄】【生】【虫】【蜘】【蛛】【池】【搭】【建】【蜘】【蛛】【池】【程】【序】【蜘】【蛛】【池】【下】【载】【地】【址】【蜘】【蛛】【池】【源】【码】【黑】【帽】【蜘】【蛛】【池】【云】【蜘】【蛛】【池】【阿】【里】【云】【蜘】【蛛】【池】【蜘】【蛛】【池】【怎】【么】【搭】【建】【蜘】【蛛】【池】【搭】【建】【教】【程】【如】【何】【搭】【建】【蜘】【蛛】【池】【小】【霸】【王】【蜘】【蛛】【池】【教】【程】【蜘】【蛛】【池】【百】【度】【收】【录】【查】【询】【百】【度】【秒】【收】【录】【蜘】【蛛】【池】【百】【度】【收】【录】【蜘】【蛛】【池】【百】【度】【蜘】【蛛】【池】【蜘】【蛛】【池】【程】【序】【破】【解】【版】【阿】【里】【蜘】【蛛】【池】【破】【解】【版】【小】【霸】【王】【蜘】【蛛】【池】【破】【解】【版】【免】【费】【蜘】【蛛】【池】【程】【序】【蜘】【蛛】【池】【程】【序】【源】【码】【免】【费】【蜘】【蛛】【池】【蜘】【蛛】【池】【出】【租】【无】【名】【蜘】【蛛】【池】【蜘】【蛛】【池】【软】【件】【蜘】【蛛】【池】【采】【集】【关】【键】【字】【蜘】【蛛】【池】【原】【理】
«   2019年12月   »
1
2345678
9101112131415
16171819202122
23242526272829
3031
最近发表
标签列表
网站分类
搜索
最新留言
    文章归档
    网站收藏
      友情链接
      • 订阅本站的 RSS 2.0 新闻聚合
      控制面板
      您好,欢迎到访网站!
        查看权限

      Powered By Z-BlogPHP 1.5.2 Zero Theme By 蜘蛛池

      Copyright Your zhizhu.seo6889.com.Some Rights Reserved.QQ:25496334