摘要:一內存區域虛擬機在運行時,會把內存空間分為若干個區域,根據虛擬機規范版的規定,虛擬機所管理的內存區域分為如下部分方法區堆內存虛擬機棧本地方法棧程序計數器。
前言在JVM的管控下,Java程序員不再需要管理內存的分配與釋放,這和在C和C++的世界是完全不一樣的。所以,在JVM的幫助下,Java程序員很少會關注內存泄露和內存溢出的問題。但是,一旦JVM發生這些情況的時候,如果你不清楚JVM內存的內存管理機制是很難定位與解決問題的。
一、JVM 內存區域Java虛擬機在運行時,會把內存空間分為若干個區域,根據《Java虛擬機規范(Java SE 7 版)》的規定,Java虛擬機所管理的內存區域分為如下部分:方法區、堆內存、虛擬機棧、本地方法棧、程序計數器。
1、方法區
方法區主要用于存儲虛擬機加載的類信息、常量、靜態變量,以及編譯器編譯后的代碼等數據。在jdk1.7及其之前,方法區是堆的一個“邏輯部分”(一片連續的堆空間),但為了與堆做區分,方法區還有個名字叫“非堆”,也有人用“永久代”(HotSpot對方法區的實現方法)來表示方法區。
從jdk1.7已經開始準備“去永久代”的規劃,jdk1.7的HotSpot中,已經把原本放在方法區中的靜態變量、字符串常量池等移到堆內存中,(常量池除字符串常量池還有class常量池等),這里只是把字符串常量池移到堆內存中;在jdk1.8中,方法區已經不存在,原方法區中存儲的類信息、編譯后的代碼數據等已經移動到了元空間(MetaSpace)中,元空間并沒有處于堆內存上,而是直接占用的本地內存(NativeMemory)。根據網上的資料結合自己的理解對jdk1.3~1.6、jdk1.7、jdk1.8中方法區的變遷畫了張圖如下(如有不合理的地方希望讀者指出):
去永久代的原因有:
字符串存在永久代中,容易出現性能問題和內存溢出。
類及方法的信息等比較難確定其大小,因此對于永久代的大小指定比較困難,太小容易出現永久代溢出,太大則容易導致老年代溢出。
永久代會為 GC 帶來不必要的復雜度,并且回收效率偏低。
堆內存主要用于存放對象和數組,它是JVM管理的內存中最大的一塊區域,堆內存和方法區都被所有線程共享,在虛擬機啟動時創建。在垃圾收集的層面上來看,由于現在收集器基本上都采用分代收集算法,因此堆還可以分為新生代(YoungGeneration)和老年代(OldGeneration),新生代還可以分為 Eden、From Survivor、To Survivor。
3、程序計數器程序計數器是一塊非常小的內存空間,可以看做是當前線程執行字節碼的行號指示器,每個線程都有一個獨立的程序計數器,因此程序計數器是線程私有的一塊空間,此外,程序計數器是Java虛擬機規定的唯一不會發生內存溢出的區域。
4、虛擬機棧虛擬機棧也是每個線程私有的一塊內存空間,它描述的是方法的內存模型,直接看下圖所示:
虛擬機會為每個線程分配一個虛擬機棧,每個虛擬機棧中都有若干個棧幀,每個棧幀中存儲了局部變量表、操作數棧、動態鏈接、返回地址等。一個棧幀就對應 Java 代碼中的一個方法,當線程執行到一個方法時,就代表這個方法對應的棧幀已經進入虛擬機棧并且處于棧頂的位置,每一個 Java 方法從被調用到執行結束,就對應了一個棧幀從入棧到出棧的過程。
5、本地方法棧本地方法棧與虛擬機棧的區別是,虛擬機棧執行的是 Java 方法,本地方法棧執行的是本地方法(Native Method),其他基本上一致,在 HotSpot 中直接把本地方法棧和虛擬機棧合二為一,這里暫時不做過多敘述。
6、元空間上面說到,jdk1.8 中,已經不存在永久代(方法區),替代它的一塊空間叫做 “ 元空間 ”,和永久代類似,都是 JVM 規范對方法區的實現,但是元空間并不在虛擬機中,而是使用本地內存,元空間的大小僅受本地內存限制,但可以通過 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 來指定元空間的大小。
總結JVM內存區域劃分,便于它能夠更加高效的管理自身的內存。當程序中出現這種由于JVM造成的內存溢出的情況的時候,需要根據不同的情況做不同的分析與處理。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7199.html
摘要:從使用到原理學習線程池關于線程池的使用,及原理分析分析角度新穎面向切面編程的基本用法基于注解的實現在軟件開發中,分散于應用中多出的功能被稱為橫切關注點如事務安全緩存等。 Java 程序媛手把手教你設計模式中的撩妹神技 -- 上篇 遇一人白首,擇一城終老,是多么美好的人生境界,她和他歷經風雨慢慢變老,回首走過的點點滴滴,依然清楚的記得當初愛情萌芽的模樣…… Java 進階面試問題列表 -...
摘要:運行時數據區域的學習,是學習以及機制的基礎,也是深入理解對象創建及運行過程的前提。了解內存區域劃分,是學習概念的前提。 Java 運行時數據區域的學習,是學習 jvm 以及 GC 機制的基礎,也是深入理解 java 對象創建及運行過程的前提。廢話不多說,直接進入正題: 一張圖總結 showImg(https://segmentfault.com/img/bVOMAn?w=685&h=5...
摘要:我的是忙碌的一年,從年初備戰實習春招,年三十都在死磕源碼,三月份經歷了阿里五次面試,四月順利收到實習。因為我心理很清楚,我的目標是阿里。所以在收到阿里之后的那晚,我重新規劃了接下來的學習計劃,將我的短期目標更新成拿下阿里轉正。 我的2017是忙碌的一年,從年初備戰實習春招,年三十都在死磕JDK源碼,三月份經歷了阿里五次面試,四月順利收到實習offer。然后五月懷著忐忑的心情開始了螞蟻金...
閱讀 1518·2021-11-23 09:51
閱讀 3639·2021-09-26 09:46
閱讀 2125·2021-09-22 10:02
閱讀 1818·2019-08-30 15:56
閱讀 3319·2019-08-30 12:51
閱讀 2224·2019-08-30 11:12
閱讀 2060·2019-08-29 13:23
閱讀 2323·2019-08-29 13:16