1、運行時數據區域java
1. 線程共享區併發
方法區:用於存儲被虛擬機加載的類信息、常量、靜態變量等數據。jvm
堆:用於存放對象實例(全部經過new建立的對象)。xss
2. 線程獨佔區spa
虛擬機棧:描述的是Java方法執行的內存模型。每一個方法在執行的同時都會建立一個棧幀,用於存儲局部變量表、操做數棧、動態連接、方法出口等信息。
本地方法棧:和虛擬機棧的做用相似,不一樣點在於本地方法棧主要是爲虛擬機使用到的Native方法提供服務。線程
程序計數器:是一塊較小的內存空間,是當前線程所執行的字節碼的行號指示器。對象
3. 其它
運行時常量池:方法區的一部分。用於存放編譯期生成的各類字面量和符號引用。
直接內存(堆外內存):不是jvm運行時數據區的一部分,也不是jvm規範中定義的內存區域。blog
2、內存劃分內存
1. 堆:可經過 -Xmx 和 -Xms 來分別設置最大堆內存和初始時堆內存。字符串
new(新生代):用來存放jvm剛分配的java對象。可經過 -XX:MaxNewSize 和 -XX:NewSize 來分別設置最大內存和初始時內存。
(a) eden:用來存放jvm剛分配的java對象。可經過 -XX:SurvivorRatio 來設置 eden 與1個 survivor 的比值(eden / survivor 的值)。
(b) survivor1
(c) survivor2
PS:兩個survivor空間同樣大。eden中對象在gc後不會立馬放入tenured區,會先放入survivor區中來回複製一段時間。
tenured(老年代):用於存放新生代中通過屢次gc後仍然存活的對象。可經過 -XX:NewRatio 來設置老年代與新生代的比值(老年代 / 新生代的值)。
2. 方法區
perm(永久代):可經過 -XX:PermSize 和 -XX:MaxPermSize 來指定最小值和最大值。
PS:perm區不等同於方法區,僅是Hotspot JVM 經過perm實現方法區。
JDK1.7,已經把放在永久代的字符串常量池移到堆中。
JDK1.8,撤銷永久代,引入元空間。
3. 虛擬機棧:可經過 -xss 設置每一個線程的堆棧大小。
4. 本地方法棧
3、垃圾回收(gc)
1. 回收器
新生代gc:
串行:可經過 -XX:+UseSerialGC 來強制指定。
並行:可經過 -XX:+UseParallelGC 來強制指定,用 -XX:ParallelGCThreads 來指定線程數。
併發:與老年代的併發gc配合使用。
老年代gc:
| 方式 | 新生代gc方式 | 老年代gc方式 |
| :----: | :----: |:---: |
| -XX:+UseSerialGC | 串行gc | 串行gc |
| -XX:+UseParallelGC | 並行回收gc | 並行gc |
| -XX:+UseConeMarkSweepGC | 並行gc | 併發gc |
| -XX:+UseParNewGC | 並行gc | 串行gc |
| -XX:+UseParallelOldGC | 並行回收gc | 並行gc |
| -XX:+ UseConeMarkSweepGC、-XX:+UseParNewGC | 串行gc | 併發gc |
2. 什麼時候回收
(a) 新生代中eden區內存滿時,引起普通gc。
(b) 老年代滿時,引起full gc。
(c) 永久代滿時,引起full gc。會致使class、method元信息的卸載。
3. 什麼時候拋出`OutOfMemoryException`
(a) jvm 98%的時間都花費在內存回收 (b) 每次回收的內存小於 2%