JVM內存堆布局圖解分析
JAVA能夠實現跨平臺的一個根本原因,是定義了class文件的格式標準,凡是實現該標準的JVM都能夠加載并解釋該class文件,據此也可以知道,為啥Java語言的執行速度比C/C++語言執行的速度要慢了,當然原因肯定不止這一個,如在JVM中沒有數據寄存器,指令集使用的是棧來保存中間數據...等,盡管Java的貢獻者們為執行速度的提高想了各種辦法,如JIT、動態編譯器等,以下是Leetcode中一道題目用不同的語言實現時的執行性能對比圖...
以下是JVM的一個基本架構圖,在這個基本架構圖中,棧有兩部份,Java線程棧以及本地方法棧,棧的概念與C/C++程序基本上都是一個概念,里面存放的都是棧幀,一個棧幀代表的就是一個函數的調用,在棧幀里面存放了函數的形參,函數的局部變量, 返回地址等,但是與C/C++的 一個重要區別是,C/C++里面有傳值以及傳址的區別,當傳的是一個對象時( 結構體也可以當成對象,其實就是對象~,只不過里面的方法默認都是public的,不信你可以試試,在結構體中加一個函數,編譯器也不會報錯,程序依舊運 行~~~),會將對象復到到棧中,而Java中只有基本類型才是傳值的,其他類型傳的都是引用,什么是引用,學過C/C++的就把引用當作指針理解 吧~~~,在這個基本架構圖中,可以看出JVM還定義了一個本地方法棧,本地方法棧是為Java調用本地方法【這些本地方法是由其他語言編寫的】服務的
上面的圖中看到的是JVM中棧有兩個,但是堆只有一個,每一個線程都有自已的線程棧【線程棧的大小可以通過設置JVM的-xss參數進行配置,32位系統下,一般默認的大小是512K】,線程棧里面的數據屬于該線程私有,但是所有的線程都共享一個堆空間,堆中存放的是對象數據,什么是對象數據,排除法,排除基本類型以及引用類型以外的數據都將放在堆空間中,下面來具體分析一下堆空間...
在JVM中堆空間劃分如下圖所示
上圖中,刻畫了Java程序運行時的堆空間,可以簡述成如下2條
1.JVM中堆空間可以分成三個大區,新生代、老年代、永久代
2.新生代可以劃分為三個區,Eden區,兩個幸存區
在JVM運行時,可以通過配置以下參數改變整個JVM堆的配置比例
1.JVM運行時堆的大小 -Xms堆的最小值 -Xmx堆空間的最大值 2.新生代堆空間大小調整 -XX:NewSize新生代的最小值 -XX:MaxNewSize新生代的最大值 -XX:NewRatio設置新生代與老年代在堆空間的大小 -XX:SurvivorRatio新生代中Eden所占區域的大小 3.永久代大小調整 -XX:MaxPermSize 4.其他 -XX:MaxTenuringThreshold,設置將新生代對象轉到老年代時需要經過多少次垃圾回收,但是仍然沒有被回收
在上面的配置中,老年代所占空間的大小是由-XX:SurvivorRatio這個參數進行配置的,看完了上面的JVM堆空間分配圖,可能會奇怪,為啥新生代空間要劃分為三個區Eden及兩個Survivor區?有何用意?為什么要這么分?要理解這個問題,就得理解一下JVM的垃圾收集機制(復制算法也叫copy算法),步驟如下:

來自:http://www.cnblogs.com/WJ5888/p/4374791.html