【JAVA進階架構師指南】之二:JVM篇

前言

  談到JAVA,就不得不提JVM---JAVA程序員繞不開的話題.也許有童鞋會說,我不懂JVM,可是我同樣能夠寫出JAVA代碼,我相信說這種話的童鞋,每每是隻有1-3年的初級開發人員,對JAVA理解還不深,不明白JVM的重要性,那接下來咱們來講說,爲何要學習JVM?
  1.理解JVM,才能幫助咱們寫出更好,更健壯的代碼.舉個例子,如下代碼的執行結果會是什麼呢?不少童鞋確定會說:嗯?當我傻嗎?兩個不都是true嗎?這有啥好說的,真的是這樣嗎?感興趣的童鞋能夠本身下來試一試,至於爲何是這樣的結果,在下文會解釋清楚.
file
  2.理解JVM,能夠幫助咱們提高JAVA程序的性能,排除問題.
  3.也是最重要的一點,面試必問!java

虛擬機的種類

  咱們知道,目前使用範圍最廣的虛擬機是sun公司的HotSpot VM,在這以前,sun公司發佈的第一款虛擬機是Sun Classic/Exact VM,這是世界上第一款商用虛擬機.另外其餘公司也有本身的虛擬機,好比IBM J9 VM,Google Android Dalvik VM,Apache Harmony,Microsoft VM等待,可是使用範圍最廣的仍是HotSpot.程序員

JVM內存劃分

  引用一張圖來講明:
file面試

  能夠看到,JVM主要由方法區/堆區/虛擬機棧/本地方法棧/程序計數器五個部分組成,從線程的角度來看,分爲線程公有的部分(方發區/java堆)和線程私有的部分(虛擬機棧/本地方法棧/程序計數器).數組

方法區

  存放已經被虛擬機加載的[類信息/常量/靜態變量/即時編譯後的代碼]等,有些文章也稱方法區爲永久代,主要發生的異常是內存溢出:OutOfMemoryError.另外在JDK1.6版本中,常量池(這裏特指運行時常量池,咱們通常說的常量池也都是指的運行時常量池)是存放於方法區中的(所以方法區可能會常常內存溢出),JDK1.7的時候常量池移到了JAVA堆(Heap)中,在JDK1.8的時候,已經沒有方法區了,取而代之的是一塊叫元數據(metaSpace)的空間.緩存

java堆

  java堆主要存放的是對象實例以及數組等信息,主要發生的異常仍然是內存溢出:OutOfMemoryError.而且java堆區是GC重點關注的區域.另外,咱們常說,幾乎全部的對象分配內存都是在java堆中進行,而不是說全部對象100%都在java堆中分配內存,是由於有兩種例外狀況不會在java堆中分配內存,第一種是TLAB(線程本機分配緩存),另外一種是棧上分配,既然想成爲一名架構師,童鞋們應該要弄明白什麼是TLAB和棧上分配,發揮大家的能力,盡情Google吧.微信

虛擬機棧

  java方法執行的內存模型,每一個方法在執行的時候會封裝成一個棧幀,存放[局部變量表/操做數棧/本動態鏈表/方法出口]等信息,方法的執行對應棧幀入棧和出棧的過程.棧的深度是有大小的,默認狀況下棧的內存爲1M,所以虛擬機棧除了發生內存溢出異常,還有可能發生StackOverFlowError異常.架構

本機方法棧

  和虛擬機棧做用相似,區別在於本地方法棧保存的是native方法的信息.性能

程序計數器

  當前線程執行的字節碼行號指示器,是JVM中惟一一塊沒有內存溢出異常的區域.學習

常量池

  接下來咱們再倒回來看看,文章開頭的代碼,執行結果會是什麼:
file
  127返回的是true,128返回的確是false.爲何?
  首先咱們知道,在java語言中 == 比較的是兩個對象的內存地址,只有equals方法纔是比較兩個對象是否相等,執行結果告訴咱們,值都爲127的Integer a和b內存地址是相同的,他們是同一個對象,而值爲128的Integer c和d的內存地址不一樣,他們是不一樣的兩個對象,那爲何127就是相同的對象,128就是不一樣的對象呢?還記得上文中,咱們說方法區中有一塊區域叫運行時常量池,存放的是各類常量,java語言對byte/short/char/int/string設置了常量池,好比咱們查看Integer的源碼:
file
  能夠發現,Integer的常量池範圍是-128~127,在該範圍內的Integer對象都會複用常量池中的值,所以a和b是相同對象,而超過該範圍,會從新new一個新的對象,所以c和d都是從新new出來的,地址固然不一樣,所以是false.另外String類型的常量池和前面四種類型不同,String類型的常量池是經過final來實現的.而float/double沒有常量池的概念,由於float和double自己都是科學技術法表示近似數,沒法精確計算,存在精度丟失的狀況,所以無法爲float和double建立常量池.spa

  本文咱們瞭解了JVM的內存區域,下一篇文章,讓咱們來學習類加載機制,敬請期待!

  若是以爲博主寫的不錯,歡迎關注博主微信公衆號,博主會不按期分享技術乾貨!
  file

本文由博客一文多發平臺 OpenWrite 發佈!
相關文章
相關標籤/搜索