java内存结构
我們正式講到我們的第一個知識點,叫做HotSpot VM,你們有沒有了解過的,有沒有人了解過HotSpot VM的,它是SUN公司開發的JVM虛擬機,基本的介紹我就不細說了,因為后面的內容比較多,就是關于介紹的我就不細說了,我們講的第一個知識點,JAVA內存結構,那么講到JAVA內存結構的時候,知識點其實是非常非常多的,在這個地方我就去給大家講一下JAVA內存結構,我大體的說一下內存結構,簡單的做回顧,然后我慢慢地畫個圖細說一下,首先JAVA內存結構還是分得比較多的
1. JAVA堆 JAVA HEAP第一個是堆,這是最基本的,堆其實是JVM里最核心的一塊,像你們學JAVA回收機制,包括你們要學的JVM參數調優,都是主要是圍繞著這個堆來的,那么這個堆非常重要,實際上你們也知道,主要是存放對象的實例,包括創建對象實例,數組也都是存放到堆里去的,所以堆你們學好了之后,堆里面還分一個知識點,叫做什么,叫做新生代和老年代,你們之前也聽說過了,那么在新生代里他又分什么呢,叫做from的s0區和s1區,待會我又會細講為什么又分三個區域,它是為復制算法打一個鋪墊的,我待會細說2. JAVA虛擬棧還有一個是叫做JAVA虛擬棧,它是本線程私有的,而且它是存放一些基本的數據類型的,這個我就不細說了,大家做一個了解說一下,我在畫圖的時候慢慢地去細說3. 本地方法棧本地方法棧估計沒有什么了解,有沒有人了解本地方法棧,主要是和C語言打交道的,和我們的非JAVA語言打交道的,它是通過native進行修飾的,native修飾主要作用是干嘛用的,他主要是和JNI打交道的,如果有人學習過安卓的話,你們會發現,安卓他的底層就是C語言,你就會通過JNI技術,走到native方法,走本地方法棧,走本地方法打交道,也就是和C語言進行打交道4. 方法區還有一個就是方法區,方法區好像在JDK1.8把它改了,沒有方法區這個概念了,待會說一下,但是在JDK1.8之前呢,還是有方法區的概念,方法區其實和堆是一樣的概念,但是方法區存放的是一些永久數據,那么你們存放的靜態常量信息,都會存到方法區的,那么你們之前也知道,垃圾回收機制,他基本上是不會去方法區去進行回收的,但是我跟你們講你們有一個誤區,很多人都有誤區的,就是以為垃圾回收機制,不會去方法區進行回收,這是不對的,我們會講到Minor GC,和Full GC的區別,我這一講完你就知道了,其實這個方法區里面,他也是有可能性被Full GC回收的,我待會會細說的5. 直接內存我們這里還有一個是直接內存,我在今天這個不好跟你講,因為他是和NIO相關的,他是和直接內存打交道的,這個我可能今天無法去講了,這個在講netty,講到netty框架6. 運行常量池還有一個是運行常量池,運行常量池我是單獨把它給抽出來了,其實他也是class文件里的一部分,除了類字段版本結構描述外,還有一項信息包括字面量和符號的引用,常量池其實也是方法區的一部分,我把它抽取出來給大家講了,只做一個了解7. 程序計數器 Program Counter Register這個其實沒有必要把程序計數器了解的非常深,因為程序計數器是非常底層的東西,和硬件有點打交道了,程序計數器你可以怎么去理解呢,就可以把它看做是當前線程所執行的字節碼行號指示器的值8. 執行引擎還有一個叫做執行引擎,執行引擎就非常核心了,主要是圍繞著給字節碼負責編譯成機器碼執行的9. 垃圾收集系統最核心的是垃圾收集系統,這也是我們今天要圍繞講的主題,就是垃圾回收算法這里,我待會就慢慢給大家細說
在這里我大體通過語言方面,組織花了幾分鐘的時間,來說一下基本概念,我再畫圖給大家細講一下吧,圖你們一定要記清楚了,首先你們要知道,JAVA源代碼自從編譯了之后,是成為什么文件,是不是class文件,所以我們這里會有一個Class文件,記住,有的人叫字節碼也可以,那下節課我們會詳細的學到字節碼文件的,叫做Class文件,編譯成Class文件之后,我們的程序如果想加載的時候,它是怎樣去執行的,在這邊我可以給大家說一下,你們有沒有了解過classloader,有多少人了解過類加載器的,這部分叫做類加載器,你們如果把類加載器學會了之后,熱部署原理您們有沒有了解過,熱部署的原理就是通過類加載器,類加載器我們自己怎么手寫一個出來,這里還有一個內存空間,我畫一個比較大的一個區域,這個內存空間其實他的知識就比較多了,在內存空間里面又會覆蓋一些知識點
1. 第一個叫做方法區,方法區我就通過白話文去講了,方法區你們說一下,方法區里面主要是存放哪些數據,基本的包括類的信息,還有常量,靜態,這些都是成了方法區了,方法區在JDK1.8之前,叫做什么呢,叫做永久區,永久區的概念是什么意思呢,垃圾回收機制基本上不會去那里回收,確確實實不會去回收的,但是我跟你講一下,說一個誤區,Full GC,Full GC其實也是會去回收到方法區的,我跟你講一下他會在什么場景下,會去回收方法區2. 然后第二個是堆,這也是非常非常核心的了,為什么比較核心,堆內存主要是存放了哪些信息呢,基本的只要是使用new的對象,定義的一些數組,他全部都是存放在堆內存里的你們如果想學習JVM,像堆一定是要搞得非常深的,因為我們會講垃圾回收機制算法,包括JVM參數的調優,都是圍繞著堆進行來的,有的人可能遇到內存溢出,內存溢出和內存泄露有什么區別呢,這個其實我會詳細講到內存泄露的問題,這里我們說一個問題,有的時候不要太多的常量,包括靜態信息的,尤其我們的JAVA項目當中,定義非常多的常量信息,那么就會怎么樣呢,就會導致什么問題呢,導致方法區占的內存非常大,很容易產生內存泄露的問題的3. JAVA棧,只要你們剛學JAVASE的時候,基本的數據類型,都會存在棧里面,局部變量,這個時候我就講一下線程共享的問題,這個棧線程共不共享,記住它是不共享的,每個線程獨立棧,不會產生共享的問題,所以這是為什么你們在多線程的情況下,操作局部變量的時候,為什么不會產生線程安全的問題,因為他們不會共享,每個線程都是獨立出來的,所以你在這里也可以聯想到我在之前講過的什么呢,本地內存,方法區和堆內存都會共享的,方法區是多線程會共享的,包括堆內存,都是會共享的,所以為什么會 產生什么問題呢,線程安全問題4. JAVA本地方法棧,其實你們之前學習了本地方法棧的,你們想想在哪里講過本地方法棧的,不是本地內存,那是IO里面的,你一般發現本地方法棧他代碼是怎么調用的呢,方法是通過native進行修飾的,你們都用過的,只是沒有細細的去了解過,本地方法棧相當于JAVA語言調用外部語言,外部語言你們知道是什么意思沒有,JAVA的最底層是什么,是C語言記住,JAVA調用外部語言是通過什么,是通過C語言,我不知道有沒有人做過安卓開發的,在安卓開發的應用層,應用層是什么,叫做JAVA api 所以只要你做安卓,因為你最上一層是JAVA api,安卓的底層是C語言,你們如果想做安卓開發,非常高的薪資待遇,要學的技術叫做JNI,JNI是干嘛用的,相當于我JAVA語言去調用C語言,去直接做操作,這樣效率會更高,如果你坐過安卓開發就會發現,為什么有些業務需求,我需要JAVA語言去調C語言呢,因為如果你直接通過JAVA API直接操作的話效率是非常低的,如果直接通過C語言,直接走JNI的話,這樣的話你的性能會更高,所以這也是提高性能,那么本地方法棧,他到底什么意思呢,就相當于JAVA語言調用外部語言,也就是調用C語言,那么你調用的時候會發現,方法是使用這個修飾的,使用native進行修飾的,你們想想,您們在之前的時候,講過什么鎖的時候,說過一個方法,通過native方法進行修飾的,想想,之前講CAS原理的時候,只能通過比較法,我當前修改值和期待值做比較,如果值一致的情況下,性能安全,那么這樣呢我就會怎么樣呢,只進行做修改,你可以通過這個保證線程安全問題,其實我準備好了,這個代碼你們都懂吧
package com.learn.test;import java.util.concurrent.atomic.AtomicInteger;public class Test002 {/*** 原子類* 原子類是一個線程安全的計數器* 多線程加鎖和原子類他們原理到底是不是一樣的* 他完全不一樣* 多線程加鎖提供synchronized和lock鎖* 它是悲觀類型的* 程序可能會產生阻塞和等待* 但是像Atomic原子類,* 他采用樂觀鎖機制* 程序是不會產生阻塞和等待的* 通過比較法去實現* 性能要比多線程加鎖要高* 這個方法主要是做計數用的* */private static AtomicInteger atomicInteger;public static void main(String[] args) {/*** 這個我點進去再點進去* public final int incrementAndGet() {* return unsafe.getAndAddInt(this, valueOffset, 1) + 1;* }* public final native boolean compareAndSwapInt* 這個方法能再點嗎* 不能再點了* public final native boolean compareAndSwapInt* 這個方法是什么意思,* 表示和外部語言進行打交道* 所以這個是非常底層* 通過指令集和C進行打交道* 通過CPU那一層和你做比較的* 所以為什么會非常抽象* 這個時候理解本地方法棧沒有*/atomicInteger.incrementAndGet();}
}
5. 在這里會有一個垃圾回收機制,你們在學垃圾回收機制的時候,主要是學算法,算法你們知道有幾種嗎,常用的就這幾種,標記清除,復制算法,還有標記壓縮,分代算法,引用計數法現在沒被用到過,只換了個名稱,有方法區概念,只是換了個名稱,沒有永久區概念的,換了名稱Method Area方法區
6. 垃圾回收機制回憶起來是非常非常繞的,比如這邊叫做本地方法棧,本地方法棧會調用本地方法接口,本地方法接口就是走JNI和C語言直接打交道的,如果你和本地方法接口走好了之后呢,這個時候再會走一個本地方法庫,本地方法庫干嘛用的,本地方法庫走這個接口,本地方法棧調用這個接口,你可以理解成在C語言這一層,這一層我把它叫做JNI,本地方法棧走JAVA語言JNI技術,調用C語言的本地方法庫,就是這樣的7. 這里還有一個執行引擎,相當與做一個數據的指令,去執行你的字節碼文件的,叫做數據和指令8. 還有一個叫PC寄存器,PC寄存器其實是比較底層的,我又總結一句話,相當于當前線程字節碼行號指示器,代碼存到哪個地方去了本地接口會調用執行引擎,執行引擎再會去調用PC寄存器的,走的是內存地址,PC寄存器調用執行引擎,去做一個字節碼的一個執行,類加載器會走內存空間,JAVA內存結構,下面那一層可以只是了解,不是核心,如果整個記下了也OK
?
總結
- 上一篇: Nginx_负载均衡配置讲解
- 下一篇: finalize方法作用