jvm┃java內存區域,跳槽大廠必會知識點!

正文約: 2000字java

預計閱讀時間: 6分鐘程序員

文章首發於個人wexin  公衆hao:moon聊技術,歡迎你們關注網絡

[jvm┃java內存區域,跳槽大廠必會知識點!](https://mp.weixin.qq.com/s/pbYTN0B1yYFXSRohlq6Meg "jvm┃java內存區域,跳槽大廠必會知識點!")多線程

目錄
目錄
前言
正文
1.程序計數器
2.虛擬機棧
3.本地方法棧
4.堆
5.方法區
6.直接內存
結語
前言
在java的使用過程中,咱們會發現java的內存是本身釋放的,並不像C、C++代碼那樣,每一起內存都須要程序員本身去維護,可是在如此便捷的同時可能也會出現不少問題,好比內存溢出,內存泄漏更很差排查了,因此今天的文章中,moon會帶你們先了解java的內存區域的究竟是怎樣的,以及各個組件的做用是什麼,讓你一點一點翻越虛擬機內存管理這座大山。架構

正文
咱們先來看一張圖:jvm

preview
這張圖就是一個java虛擬機運行時數據圖,深色區域表明是線程共享的區域,java程序在運行的過程當中會把他管理的內存劃分爲若干個不一樣的數據區域,每一起的數據區域所負責的功能都是不一樣的,他們也有不一樣的建立時間和銷燬時間,本文將會從這張圖開始一一展開,清晰的告訴你每個模塊的做用。佈局

1.程序計數器
程序計數器就像是控制城市交通的紅綠燈同樣,是整個系統的中樞。在jvm中,它就是程序控制流的指示器,循環,跳轉,異常處理,線程的恢復等工做都須要依賴程序計數器去完成。
程序計數器是線程私有的,它的生命週期是和線程保持一致的,咱們知道,N個核心數的CPU在同一時刻,最多有N個線程同時運行,在咱們真實的使用過程當中可能會建立不少線程,jvm的多線程實際上是經過線程輪流切換,分配處理器執行時間來實現的。既然涉及的線程切換,因此每條線程必須有一個獨立的程序計數器。性能

2.虛擬機棧
虛擬機棧,其描述的就是線程內存模型,也能夠稱做線程棧,也是每一個線程私有的,生命週期與線程保持一致。在每一個方法執行的時候,jvm都會同步建立一個棧幀去存儲局部變量表,操做數棧,動態鏈接,方法出口等信息。一個方法的生命週期就貫徹了一個棧幀從入棧到出棧的所有過程。 局部變量表應該是咱們接觸的最多的,裏面存儲了java的8大基本數據類型(byte、short、char、int、float、long、double、boolean)、對象引用(reference類型,不是對象自己,是指向對象的引用)和returnAddress類型(指向一條字節碼指令的地址)。局部變量表的存儲單位是局部變量槽(slot),long和double類型會佔據兩個變量槽,其他類型只佔用一個,可是每個變量槽的大小是由jvm本身決定的。線程

3.本地方法棧
本地方法棧的概念很好理解,咱們知道,java底層用了不少c的代碼去實現,而其調用c端的方法上都會有native,表明本地方法服務,而本地方法棧就是爲其服務的。設計

4.堆
堆能夠說是jvm中最大的一起內存區域了,它是全部線程共享的,無論你是初學者仍是資深開發,多少都會據說過堆,畢竟幾乎全部的對象都會在堆中分配。

咱們先從分配內存的角度看看堆是怎麼樣的:


其實這就是一個最真實的堆,可能有些同窗會以爲我說的不對,應該還有新生代,老年代,永久代,伊甸區,servivor區等等。這種說法基於某種邏輯上說是對的,可是並非標準,它只是某些垃圾回收器的設計理念,須要新生代,老年代收集器搭配才能工做。

咱們來講說TLAB(thread local allocation buffer),TLAB的數量和線程數是一一對應的,也就是說,TLAB是線程私有的,在堆空間中分配,對象會首先存放在這個線程私有的TLAB中,能夠提高線程分配的效率。

5.方法區
方法區也是全部線程共享的區域,它存儲了被jvm加載的類型信息、常量、靜態變量等數據。
運行時常量池就是方法區的一部分,編譯期生成的各類字面量與符號引用就存儲在其中。

6.直接內存
這部分數據並非jvm運行時數據區的一部分,nio就會使用到直接內存,也能夠說堆外內存,一般會配合虛引用一塊兒去使用,就是爲了資源釋放,會將堆外內存開闢空間的信息存儲到一個隊列中,而後GC會去清理這部分空間。

堆外內存優點在 IO 操做上,對於網絡 IO,使用 Socket 發送數據時,可以節省堆內存到堆外內存的數據拷貝,因此性能更高。看過 Netty 源碼的同窗應該瞭解,Netty 使用堆外內存池來實現零拷貝技術。對於磁盤 IO 時,也可使用內存映射,來提高性能。另外,更重要的幾乎不用考慮堆內存煩人的 GC 問題。可是既然是內存。也會受到本機總內存的限制,

結語
今天和你們聊了聊java內存區域是怎樣的,而這部份內容都是比較標準化得一個體現,並無摻雜垃圾回收相關的知識,也沒有摻雜jvm具體實現的相關邏輯,咱們知道這是一個基礎的架構,咱們在開發中默認使用的jvm是hotspot,它是SunJDK和OpenJDK中所帶的虛擬機,也是目前使用範圍最廣的Java虛擬機,他們都是基於jvm規範去開發的,因此瞭解規範以後再去學其餘深刻的實現,不要各個知識點紊亂的去學。

下一篇文章我會和你們聊聊對象的建立和對象的內存佈局相關知識。

下期見,我是moon,記得關注點贊~

相關文章
相關標籤/搜索