JVM虛擬機基礎知識

1. Java的發展

Java之父:詹姆斯·高斯林html

2. Java的技術體系

  1. Java 程序設計語言
  2. JVM
  3. class文件格式
  4. 編譯器
  5. Java API
  6. 第三方Java類庫

三個版本:java

  1. Java SE(Java Standard edition)
  2. Java ME(Micro Edition)
  3. Java EE(Java Enterprise Edition)

3. JVM的安裝

$ wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-x64.tar.gz"
$ tar zxf jdk-8u141-linux-x64.tar.gz -C /usr/local/
$ vi /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_141
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
$ source /etc/profile

4. JDK、JRE、JVM的關係

JDK(Java Development Kit)
JRE(Java Runtime Environment)
JVM(Java Virtual Machine)linux

官方結構圖:https://docs.oracle.com/javase/8/docs/web

5.Java8的新特性

  1. 引入lambda表式式
  2. Nashorn JavaScript引擎,使用Metaspace 代替PermGen space
  3. Date API
  4. 更好的類型判斷

6.Java 虛擬機產品

  1. Sun Classic VM :第一款商用虛擬機,只能使用純解釋器的方式來執行Java代碼。已被淘汰
  2. Exact VM (Exact Memory Management) : 編譯器和解釋器混合工做以及兩級及時編譯器,只在solaris平臺發佈
  3. HotSpot VM: Longview Technologies-->SUN-->Oracle
  4. KVM(Kilobyte): 簡單、輕量、高度可移植,在手機平臺運行。運行速度慢
  5. JRockit: BEA--> Oracle,專一服務端應用,優點:垃圾收集器+MissionControl服務套件
  6. J9( IBM Technology for Java Virtual Machine IT4j ): IBM公司開發,用於IBM的產品
  7. dalvik: Google公司設計,Android平臺核心組成部分之一
  8. Mircosoft JVM:
  9. Azul VM: 高性能,HotSpot 基礎上改進
  10. Liquid VM: 高性能,BEA公司開發,自己至關於一個操做系統
  11. TaobaoVM: 根據OpenJDK深度定製

7.JVM內存管理

1. 線程共享區

1.1. 方法區

  1. 保存類的元數據
  2. 元數據包括類型信息、常量池、域信息、方法信息
  3. 在HotSpot虛擬機中,方法區也被成爲永久區
  4. 雖然叫作永久區,可是在永久區的對象也能夠被GC回收

1.1.1 運行時常量池

  1. 方法區的一部分
  2. 用於存放編譯器生成的各類字面量和符號引用

1.2. Java堆

  1. 存放對象實例
  2. 垃圾收集器管理的主要區域
  3. 新生代、老年代
  4. OutofMemoryError:內存溢出

2. 線程獨佔區

2.1. Java虛擬機棧

  1. 描述的是Java方法執行的動態內存模型
  2. Java虛擬機棧主要被用來存放基本類型的變量,如:int、short、long、byte、float、double、boolea、char、對象引用
  3. StackoverflowError: 棧內存溢出,可使用-XSS指定虛擬機棧的大小,棧的大小決定了函數調用的最大可達深度
  4. 虛擬機棧爲虛擬機執行Java方法

2.2. 本地方法棧(Native Method Stacks)

  1. 本地方法棧用來執行Native方法

2.3. 程序計數器(Program Counter Register)

  1. 每個線程都有一個獨立的程序計數器,用來記錄下一條須要執行的計算機指令
  2. 程序計數器是線程獨有的一塊內存空間。這塊內存是線程私有,生命週期與線程保持一致
  3. 若是當前線程正在執行一個Java方法,則程序計數器記錄正在執行的Java字節碼地址,若是當前線程正在執行一個本地方法,則程序計數器爲空
  4. 惟一一個在Java虛擬機中內有規定任何OutofMemoryError狀況的區域

8. 對象

8.1 對象的建立

1.給對象分配內存的方式

  1. 指針碰撞
  2. 空閒列表

2. 線程的安全性問題

  1. 線程同步(須要加鎖,效率低)
  2. 本地線程分配緩衝

3. 初始化對象

4. 執行構造方法

8.2對象的結構

1.自身運行時數據(Mark Word)算法

  • 哈希值
  • GC分代年齡
  • 鎖狀態標識
  • 線程持有的鎖
  • 偏向線程ID
  • 偏向時間戳
    佔用的空間:32位機器:32bit;64位機器:64bit
  1. 類型指針apache

    2.InstanceData

3.

8.3 對象的訪問定位

1.使用句柄
2.直接指針ubuntu

9.垃圾回收

9.1 如何判斷對象爲垃圾對象?

  1. 引用計數法

在對象中添加一個引用計數器,當有地方引用這個對象時計數器的值就+1,當引用失效時,計數器的值就-1
弊端:當對象循環引用時不能識別是否爲垃圾對象
*基本沒有JVM在使用瀏覽器

  1. 可達性分析法

做爲GCroot的對象tomcat

  • 虛擬機棧
  • 方法區的類屬性所引用的對象
  • 方法區中常量所引用的對象
  • 本地方法棧中引用的對象

JDK8使用的垃圾回收器: parallel安全

9.2 回收算法

  1. 標記-清除算法
    經過可達性分析法標記-->清楚
    缺點:效率較低、空間問題(出現不少不連續的內存空間)
  2. 複製算法
    把使用中的內存複製一份從新按順序排列
    缺點:內存只能用一半,不適用於老年代
  3. 標記-整理算法
    讓全部存活的對象都向一端移動,而後清理掉邊界之外的內存
  4. 分代收集算法

  • 新生代
    • Eden 伊甸園
    • Survivor 存活區
    • Tenured Gen
  • 老年代

9.3 垃圾收集器

1. serial收集器

  1. 歷史最悠久
  2. 使用複製算法
  3. 單線程,垃圾收集時必須暫停其餘全部的工做線程,直到收集結束
  4. 虛擬機運行在Client模式下的新生代收集器
  5. 用於桌面應用

2. ParNew收集器

  1. 多線程收集
  2. 虛擬機運行在Server模式下首選的新生代收集器

3. parallel Scavenge收集器

  1. 適用複製算法(新生代內存)
  2. 多線程收集器
  3. 達到可控制的吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)
  4. -XX:MaxGCPauseMillis 垃圾收集器停頓時間
  5. -XX:GCTimeRatio 吞吐量大小 (0-100)

4. cms(Concurrent Mark Sweep)收集器

  1. 運做步驟
    標記清除--併發標記--從新標記--併發清除
  2. 優勢
  • 併發收集
  • 低停頓
  1. 缺點
  • 佔用大量的CPU資源
  • 沒法處理浮動垃圾
  • 出現Concurrent Mode Failure
  • 基於標記清除算法,會產生大料的空間碎片

5. G1(Garbage-First)收集器

面向服務端應用的垃圾收集器
優點:

  1. 並行與併發, 使用多個CPU來縮短Stop-The-Word停頓時間
  2. 分代收集
  3. 空間整合:總體上看基於標記-整理算法,局部上看基於複製算法
  4. 可預測停頓

運做步驟:

  1. 初始標記
  2. 併發標記
  3. 最終標記
  4. 篩選回收 Remembered Set

10 . 內存分配

10.1 優先分配到Eden區

10.2 大對象直接進入老年代

10.3長期存活的對象進入老年代

10.4 空間分配擔保

10.5 動態對象的年齡判斷

11. JVM工具

https://docs.oracle.com/javase/8/docs/technotes/tools/index.html#

11.1 jps (Java Process Status)

jenkins@ubuntu-OptiPlex-7040:~$ jps
13154 Bootstrap
12191 Jps

參數:

# -l :虛擬機執行主類名稱或者jar包的名稱
jenkins@ubuntu-OptiPlex-7040:~$ jps  -l
13154 org.apache.catalina.startup.Bootstrap
12462 sun.tools.jps.Jps
# -m :主類接收的參數
jenkins@ubuntu-OptiPlex-7040:~$ jps  -m
13154 Bootstrap start
12552 Jps -m
# -v :JVM接收的參數
jenkins@ubuntu-OptiPlex-7040:~$ jps  -v
13154 Bootstrap -Djava.util.logging.config.file=/home/jenkins/tomcat/jenkins/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/home/jenkins/tomcat/jenkins -Dcatalina.home=/home/jenkins/tomcat/jenkins -Djava.io.tmpdir=/home/jenkins/tomcat/jenkins/temp
12675 Jps -Denv.class.path=.:/home/ubuntu/software/jdk/jdk1.8.0_151/lib:/home/ubuntu/software/jdk/jdk1.8.0_151/jre/lib -Dapplication.home=/home/ubuntu/software/jdk/jdk1.8.0_151 -Xms8m

11.2 jstat

虛擬機統計信息監控:類裝載、內存、垃圾收集、JIT編譯等運行數據

11.3 jinfo

實時查看和調整虛擬機各項參數

11.4 jmap

生產堆轉儲快照

$ jmap -dump:format=b,file=jenkins.bin 13154
Dumping heap to /home/jenkins/jenkins.bin ...
Heap dump file created

-XX:+HeapDumpOnOutofMemoryError : 虛擬機在OOM異常出現後自動生成dump文件

# 顯示堆中對象通訊信息
$ jmap -histo 13154 | less

11.5 jhat

功能:分析jamp生成的堆轉儲快照
通常不會在生產服務器上進行分析,很是耗CPU和內存,不經常使用

jenkins@ubuntu-OptiPlex-7040:~$ jhat jenkins.bin 
Reading from jenkins.bin...
Dump file created Thu Feb 14 11:43:45 CST 2019
Snapshot read, resolving...
Resolving 12022774 objects...
Chasing references, expect 2404 
dots
Eliminating duplicate references
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

瀏覽器訪問http://ip:7000 查看分析結果

11.7 jstack

功能: 生成虛擬機當前時刻的線程快照,用來定位線程出現長時間停頓的緣由,如線程見死鎖、死循環、請求外部資源致使的長時間等待等

jstack -l 13154

11.8 jconsole

  1. 內存監控
  2. 線程監控
  3. 死鎖

11.9 jvisualvm

12. 性能調優

調優須要的技能:

  1. 知識
  2. 工具
  3. 數據
  4. 經驗
相關文章
相關標籤/搜索