JVM----Java内存区域
生活随笔
收集整理的這篇文章主要介紹了
JVM----Java内存区域
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
運行時數據區域
? ? ? ? jvm在執行Java程序時會把他所管理的區域劃分為若干個不同的數據區域,這些區域各有各自的用途。
如圖:
1.程序計數器 ? ? ? ?程序計數器是一塊較小的內存空間,可以看做是當前線程所執行的字節碼的行號指示器。每條線程都有一個獨立的程序計數器,各線程之間的計數器互不影響。如果線程在執行一個java方法,則計數器記錄的是正在執行的虛擬機字節碼指令的地址,在執行native方法時,計數器的值為空。并且在java虛擬機規范中沒有在此區域規定任何的outOfMemoryError異常。 2.java虛擬機棧 ? ? ? ?java虛擬機棧也是線程私有的,且生命周期和線程相同,其描述的是java方法執行的內存模型。在方法執行時,創建一個棧幀,用于存儲局部變量表,操作數棧,動態鏈接,方法出口等信息。此內存區域就是我們常說的棧內存。其中,局部變量表存放了編譯器可知的各種基本數據類型。其中long和double占用兩個局部變量空間,其他的占用一個。在進入方法時,此局部變量空間就被唯一確定。 ? ? ? ?java虛擬機規范規定了兩種異常狀況:線程請求的棧深度大于虛擬機所允許的深度時,拋出StackOverflowError異常。如果擴展時,無法申請到足夠的內存,拋出OutOfMemoryError異常。當然我們也可以設置系統允許分配的棧深度。 3.本地方法棧 ? ? ? ?本地方法棧與java虛擬機棧類似,不過java虛擬機棧為虛擬機棧執行java方法服務,而本地方法棧則為虛擬機執行Native方法服務。Sun HotSpot虛擬機把本地方法棧和虛擬機棧合二為一。 4.java堆 ? ? ? ?java堆是java虛擬機管理的內存在中最大的一塊。是線程共享的。java堆也是垃圾回收的主要區域,因此很多時候也會被稱為“GC堆”,并且現在的收集器都是采用的分代收集算法(GC算法介紹請看:http://www.cnblogs.com/Booker808-java/p/9063677.html),所以java堆還可以細分為新生代和老年代,新生代再細致點還可以分為Eden區、From Survivor區、To Survivor區,并且為了防止在線程共享下產生的分配區域的安全問題,java堆也會劃分出多個線程私有的分配緩沖區(TLAB),其實吧,無論怎么劃分,堆都是用來存儲對象實例的,,之所以劃分這么多區域,主要就是為了更高效的回收內存,更高效的分配內存。 5.方法區 ? ? ? ?線程共享的區域,用于存儲已被虛擬機加載的類信息,常量,靜態變量,即時編譯器編譯后的代碼等。方法區也是屬于堆的一部分,但是為了區分開來,也可以叫做非堆這個區域的回收主要針對常量池的回收和對類型的卸載。當方法區無法滿足內存分配需求時,會拋出OutOfMemoryError異常。 6.運行時常量池 ? ? ? ?運行時常量池也是方法區的一部分,class文件除了含有類的版本、字段、方法、接口等描述信息外(這些信息都是通過十六進制的符號引用來代替的),還有一項就是常量池,專門用來存放編譯期間生成的各種字面量(這里通常指final static聲明的字段)和符號引用,這些符號引用一般都是描述什么字段類型信息啊、方法類型信息等,運行時常量對class文件常量池另一個重要的特征就是具備動態性,常量可以在運行時被放入常量池。 對象的創建 1.對象的創建 ? ? ? ? java是個面向對象語言,語言層面上,是通過new關鍵字來進行創建對象的,但是在虛擬機中,創建對象又是個怎么樣的過程呢??當new指令出來時,會去常量池中檢查是否能定位到該類的符號引用,當檢查通過之后,接下來就是為新生對象進行內存分配,等同于在堆中劃分出一塊區域。這時,問題來了,如果java堆中的內存是絕對完整的,所有的用過的內存都放在一邊,沒用過的放在另一邊,中間放著一個指針作為分界點的指示器,那么分配內存的動作其實就是把那個指針指向空閑空間那邊挪動一小塊,這一小塊就是屬于我們對象的,這種分配方式屬于“指針碰撞”。 ? ? ? ? 如果java堆內存是不完整的,是雜亂不堪的,這個時候指針碰撞根本不可能正常工作,,那么虛擬機就要維護一個列表,記錄在堆上有哪些區域是可以被使用的,然后在分配內存時,在列表上找到一塊足夠大的空間分配給對象,同時更新列表上的記錄。這種分配方式可以稱為“空閑列表”,選取哪種方式完全取決于我們的堆的內存是否是規整的,而java堆是否規整又取決于垃圾收集器是否帶有自動壓縮整理功能。 2.并發下的內存分配 ? ? ? ?在劃分可用空間之外,還有一個很重要的因素就是,在多線程環境下(因為堆是線程共享的,所以這種情況是存在的),指針碰撞方式是存在線程安全問題的。當指針還在為線程A分配時(還沒分配完),這時線程B又使用了原來的指針來分配內存。兩種解決方式: (1)采用同步的方式; (2)把內存劃分的動作按照不同的線程劃分在不同的區域進行,就是說每個線程在堆上會預先分配好一小塊私有的內存區域,稱之為本地線程緩沖分配(TLAB) 哪個線程要分配內存,就在哪個線程的TLAB上劃分,如果TLAB區域劃分完了,就再進行同步,這樣也可以內存劃分時提高效率。轉載于:https://www.cnblogs.com/Booker808-java/p/9225706.html
總結
以上是生活随笔為你收集整理的JVM----Java内存区域的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 法向量影响光源照射物体后,物体产生的视觉
- 下一篇: mysql创建表和数据库