java主要内存区域_可能是把Java内存区域讲的最清楚的一篇文章
該樓層疑似違規已被系統折疊?隱藏此樓查看此樓
介紹下 Java 內存區域(運行時數據區)
Java 對象的創建過程(五步,建議能默寫出來并且要知道每一步虛擬機做了什么)
對象的訪問定位的兩種方式(句柄和直接指針兩種方式)
拓展問題:
String類和常量池
8種基本類型的包裝類和常量池
Java程序員必看文檔
1 概述
對于 Java 程序員來說,在虛擬機自動內存管理機制下,不再需要像C/C++程序開發程序員這樣為內一個 new 操作去寫對應的 delete/free 操作,不容易出現內存泄漏和內存溢出問題。
2 運行時數據區域
Java 虛擬機在執行 Java 程序的過程中會把它管理的內存劃分成若干個不同的數據區域。
這些組成部分一些事線程私有的,其他的則是線程共享的。
線程私有的:
程序計數器
虛擬機棧
本地方法棧
線程共享的:
堆
方法區
直接內存
2.1 程序計數器
程序計數器是一塊較小的內存空間,可以看作是當前線程所執行的字節碼的行號指示器。字節碼解釋器工作時通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等功能都需要依賴這個計數器來完。
2.2 Java 虛擬機棧
與程序計數器一樣,Java虛擬機棧也是線程私有的,它的生命周期和線程相同,描述的是 Java 方法執行的內存模型。
Java 內存可以粗糙的區分為堆內存(Heap)和棧內存(Stack),其中棧就是現在說的虛擬機棧,或者說是虛擬機棧中局部變量表部分。
2.3 本地方法棧
和虛擬機棧所發揮的作用非常相似,區別是: 虛擬機棧為虛擬機執行 Java 方法 (也就是字節碼)服務,而本地方法棧則為虛擬機使用到的 Native 方法服務。 在 HotSpot 虛擬機中和 Java 虛擬機棧合二為一。
2.4 堆
Java 虛擬機所管理的內存中最大的一塊,Java 堆是所有線程共享的一塊內存區域,在虛擬機啟動時創建。此內存區域的唯一目的就是存放對象實例,幾乎所有的對象實例以及數組都在這里分配內存。
Java 堆是垃圾收集器管理的主要區域,因此也被稱作GC堆(Garbage Collected Heap).從垃圾回收的角度,由于現在收集器基本都采用分代垃圾收集算法,所以Java堆還可以細分為:新生代和老年代:在細致一點有:Eden空間、From Survivor、To Survivor空間等。進一步劃分的目的是更好地回收內存,或者更快地分配內存。
2.5 方法區
方法區與 Java 堆一樣,是各個線程共享的內存區域,它用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。雖然Java虛擬機規范把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做 Non-Heap(非堆),目的應該是與 Java 堆區分開來。
HotSpot 虛擬機中方法區也常被稱為 “永久代”,本質上兩者并不等價。僅僅是因為 HotSpot 虛擬機設計團隊用永久代來實現方法區而已,這樣 HotSpot 虛擬機的垃圾收集器就可以像管理 Java 堆一樣管理這部分內存了。但是這并不是一個好主意,因為這樣更容易遇到內存溢出問題。
相對而言,垃圾收集行為在這個區域是比較少出現的,但并非數據進入方法區后就“永久存在”了。
2.6 運行時常量池
運行時常量池是方法區的一部分。Class 文件中除了有類的版本、字段、方法、接口等描述信息外,還有常量池信息(用于存放編譯期生成的各種字面量和符號引用)
既然運行時常量池時方法區的一部分,自然受到方法區內存的限制,當常量池無法再申請到內存時會拋出 OutOfMemoryError 異常。
JDK1.7及之后版本的 JVM 已經將運行時常量池從方法區中移了出來,在 Java 堆(Heap)中開辟了一塊區域存放運行時常量池。同時在 jdk 1.8中移除整個永久代,取而代之的是一個叫元空間(Metaspace)的區域
2.7 直接內存
直接內存并不是虛擬機運行時數據區的一部分,也不是虛擬機規范中定義的內存區域,但是這部分內存也被頻繁地使用。而且也可能導致OutOfMemoryError異常出現。
JDK1.4中新加入的 NIO(New Input/Output) 類,引入了一種基于通道(Channel) 與緩存區(Buffer) 的 I/O 方式,它可以直接使用Native函數庫直接分配堆外內存,然后通過一個存儲在 Java 堆中的 DirectByteBuffer 對象作為這塊內存的引用進行操作。這樣就能在一些場景中顯著提高性能,因為避免了在 Java 堆和 Native 堆之間來回復制數據。
本機直接內存的分配不會收到 Java 堆的限制,但是,既然是內存就會受到本機總內存大小以及處理器尋址空間的限制。
3 HotSpot 虛擬機對象探秘
通過上面的介紹我們大概知道了虛擬機的內存情況,下面我們來詳細的了解一下 HotSpot 虛擬機在 Java 堆中對象分配、布局和訪問的全過程。
3.1 對象的創建
下圖便是 Java 對象的創建過程,我建議最好是能默寫出來,并且要掌握每一步在做什么。
總結
以上是生活随笔為你收集整理的java主要内存区域_可能是把Java内存区域讲的最清楚的一篇文章的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《App后台开发运维与架构实践》第3章
- 下一篇: java防止undo空间撑爆_秒杀系统设