學習JVM的一點簡單筆記,宋紅康老師jvm講的很好,感謝,
尚硅谷JVM全套教程,百萬播放,全網巔峰(宋紅康詳解java虛擬機)
Runtime Data Area運行時資料區





紅色區域:一個行程(一個虛擬機實體)一份(共用),灰色區域:一個執行緒一份

95%(大多數的垃圾回收集中在Heap堆區,5%在Method Area方法區——>元空間)
堆疊沒有垃圾回收,因為只有簡單的入堆疊出堆疊操作,但有可能會溢位OOM
pc暫存器也沒有垃圾回收,
每個JVM只有一個Runtime實體(一個JVM對應一個Runtime,單例),即為運行時環境,相當于Runtime Data Area,運行時環境
執行緒

非守護執行緒執行完,都剩下守護執行緒,虛擬機停止,

Pc暫存器(程式計數器Pc Register)
JVM中pc暫存器是對物理pc暫存器的一種抽象模擬,
指示下一段地址,沒有垃圾回收GC 、OOM



package com.hut.djh;
/**
* @Author: 禿頭不用洗發水
* @Date: 2021-02-19
* @Description:
*/
public class PCRegisterTest {
public static void main(String[] args) {
int i = 10;
int j = 20;
int k = i + j;
String s = "abc";
System.out.println(i);
System.out.println(k);
}
}
反編譯

Code:
stack=2, locals=5, args_size=1
0: bipush 10
2: istore_1
3: bipush 20
5: istore_2
6: iload_1
7: iload_2
8: iadd
9: istore_3
10: ldc #2 // String abc
12: astore 4
14: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintSt
ream;
17: iload_1
18: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
21: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintSt
ream;
24: iload_3
25: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
28: return
常量池:
Constant pool:
#1 = Methodref #6.#26 // java/lang/Object."<init>":()V
#2 = String #27 // abc
#3 = Fieldref #28.#29 // java/lang/System.out:Ljava/io/PrintStream;
#4 = Methodref #30.#31 // java/io/PrintStream.println:(I)V
#5 = Class #32 // com/hut/djh/PCRegisterTest
#6 = Class #33 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/hut/djh/PCRegisterTest;
#14 = Utf8 main
#15 = Utf8 ([Ljava/lang/String;)V
#16 = Utf8 args
#17 = Utf8 [Ljava/lang/String;
#18 = Utf8 i
#19 = Utf8 I
#20 = Utf8 j
#21 = Utf8 k
#22 = Utf8 s
#23 = Utf8 Ljava/lang/String;
#24 = Utf8 SourceFile
#25 = Utf8 PCRegisterTest.java
#26 = NameAndType #7:#8 // "<init>":()V
#27 = Utf8 abc
#28 = Class #34 // java/lang/System
#29 = NameAndType #35:#36 // out:Ljava/io/PrintStream;
#30 = Class #37 // java/io/PrintStream
#31 = NameAndType #38:#39 // println:(I)V
#32 = Utf8 com/hut/djh/PCRegisterTest
#33 = Utf8 java/lang/Object
#34 = Utf8 java/lang/System
#35 = Utf8 out
#36 = Utf8 Ljava/io/PrintStream;
#37 = Utf8 java/io/PrintStream
#38 = Utf8 println
#39 = Utf8 (I)V
這些#叫做標記,前面類加載的第二步鏈接的第三步決議就是替換這些#值
10: ldc #2 :這里是從常量池取常量#2->#27,相當于兩個操作,所以下面就是12
12: astore 4:將參考值保存到本地變數表4的位置
14: getstatic #3:列印i操作 #3->#28.#29->#34,#35:#36->java/lang/System、out、Ljava/io/PrintStream;

問題1:
使用pc暫存器存盤位元組碼指令地址有什么用(為什么使用pc暫存器記錄當前執行緒的執行地址)?
回答:
因為CPU需要不斷切換各個執行緒,這時候切換回來以后,就知道接著從哪開始繼續執行,
jvm的位元組碼解釋器就需要通過,改變pc暫存器的值,來明確下一條應該執行什么樣的位元組碼指令,
問題2:
pc暫存器為什么會被設定為執行緒私有?
回答:


舉個例子,一個核執行三個執行緒,比如先執行1執行緒,然后到2執行緒,pc暫存器,就記錄1執行緒下一個要執行的位元組碼指令是第五個,類似的等別的執行緒執行完后,就回到1執行緒繼續執行5位元組碼指令,如果共享pc暫存器,就不知道之前執行到哪條指令了,
串行對應并行
串行:一個時間點單個執行,串在一起一個一個的,
并行:一個時間點多個共同執行,一個時間切面下去,有多個在執行,
一個核快速的切換執行緒,看著像并行,但實際是并發,一個時間只有一個執行緒在執行,像并行的執行,因為切換的快,但實際是并發,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/262026.html
標籤:java
