jvm定義了各個運行時數(shù)據(jù)區(qū):
Run-Time Data Areas
1)The pc Register
2)Java Virtual Machine Stacks
3)Heap
4)Method Area
5)Run-Time Constant Pool
6)Native Method Stacks
運行時數(shù)據(jù)區(qū): <=== 是一個規(guī)范,內存結構是一個實現(xiàn)
1)部分運行時數(shù)據(jù)區(qū)域是在 jvm 創(chuàng)建時創(chuàng)建 銷毀時銷毀
2)部分運行時數(shù)據(jù)區(qū)域是每個Thread都有一個的,Thread創(chuàng)建時創(chuàng)建,Thread退出時銷毀
====> 有一些是共享的 获诈,有一些是獨享的
1)The pc Register 程序計數(shù)器 <=== 每個Thread獨有
說明:
會占用一小塊的內存,其實每個運行時數(shù)據(jù)區(qū)都會占用各自小塊內存
用于當前線程所執(zhí)行的字節(jié)碼的 行號指示器
用于記錄每個線程目前執(zhí)行到 哪里了:你的代碼所對應的哪一條 字節(jié)碼指令
多個線程并發(fā)執(zhí)行時候,多個線程cpu資源搶占皂林,每一個線程都有自己的程序計數(shù)器,進而得到cpu資源時候才知道執(zhí)行到哪的了
不同的字節(jié)碼指令做不同的事情蚯撩,字節(jié)碼指令是.java文件編譯而來的
字節(jié)碼文件查看方式:javap -verbose HelloWorld.class >> HelloWorld.txt
沒有構造器础倍,自帶一個默認的空的構造器
2)Java Virtual Machine Stacks <=== 每個Thread獨有
存: 用于存放方法里面的一些局部變量
存: frames: 棧幀
A new frame is created each time a method is invoked
A frame is destroyed when its method invocation completes
入棧:方法被調用
出棧:方法執(zhí)行完
可能會出現(xiàn)的異常:
If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
即出現(xiàn)情況:線程中的計算需要的 大于 Java Virtual Machine Stacks所允許的
分析:Java Virtual Machine Stacks 存放的東西是與我們的方法相關聯(lián)的
調用方法時,會為每個方法創(chuàng)建Frame,入棧
方法執(zhí)行執(zhí)行完畢胎挎,F(xiàn)rame出棧
遞歸沒出口的時候沟启,就會不停的入棧入棧,就會一直壓壓壓犹菇,但是Java Virtual Machine Stacks這個的大小是一定的德迹,就會
StackOverflowError
3)Heap 堆 <== 所有 jvm Thread 共享的
創(chuàng)建對象實例 new Student()
存: 對象實例和數(shù)組
OutOfMemoryError
If a computation requires more heap than can be made available by the automatic storage management system, the Java Virtual Machine throws an OutOfMemoryError.
即出現(xiàn)情況:計算需要的堆 大于 自動存儲管理系統(tǒng)可用的堆
4)Method Area 方法區(qū)域 <== Thread 共享的
注意:1.8 Metaspace 元數(shù)據(jù) : 存放與.class 相關的一些信息
constant pool,
field and method data,
and the code for methods
and constructors,
即: .class字節(jié)碼文件會被加載進來
If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.
即:如果無法使方法區(qū)域中的內存滿足分配請求,則Java虛擬機將拋出OutOfMemoryError揭芍。
5)Run-Time Constant Pool <== Thread 共享的
6)Native Method Stacks 本地方法棧 <=== 每個Thread獨有
Object 類里面許多方法就是navite修飾的胳搞,
當調用Navite修飾的方法的時候,每個線程就會有一個本地方法棧
調用底層的,C等
方法:
navite 的
非navite的
前面都是JVM的6大區(qū)域肌毅,接下來這一個不屬于JVM的:
DirectByteBuffer <== java.nio 包
堆外內存 Spark 直接操作內存空間
Spark SQL筷转?
鎢絲java
直接操作內存空間,性能好悬而,如果去調用底層源碼是可以的
啟動起來呜舒,就是一個JVM進程
----------------------------------------------------華麗分割線---------------------------------------------------
JDK7: 永久代
JDK8: Metaspace 元空間
JVM參數(shù)類型:
1)標準: 穩(wěn)定
2)X: 相對變化少的
3)XX : jvm調優(yōu)的重點
a)boolean : -XX[+/-] name <==啟動 禁用
-XX:+UserG1GC
b)非boolean : -XX:name = value
java -Xint -version
java -Xcomp -version
3)XX : jvm調優(yōu)的重點
啟動一個java進程
jps 查看進程IP
【jinfo 】
用于查看正在運行的JVM參數(shù):
語法:jinfo -flag name pid
jinfo -flag PrintGCDetails pid
結果:可以看到是否開啟打印GC的參數(shù)
jinfo -flag UseG1GC pid
結果:默認是沒有開啟的,說明JDK8默認不是使用G1作為垃圾回收器的
調整 VM options : -XX:+PrintGCDetails
【元空間大小】
jinfo -flag MetaspaceSize pid
-XX:MetaspaceSize=21807104 大約20M
調整 VM options : -XX:MetaspaceSize=128m
【新生代 老年代】 <== 默認每次GC 年齡會+1
jinfo -flag MaxTenuringThreadshold pid
默認:15
【jinfo 更多】
jinfo -flag InitialHeapSize pid
結果:初始堆大小
jinfo -flag MaxHeapSize pid
結果:最大堆大小
jinfo -flags pid
結果:打出一堆VM參數(shù)
【PrintFlags系列】
-XX:+PrintFlagsInital
-XX:+PrintFlagsFinal
jinfo -XX:+PrintFlagsInital -version > temp.txt
結果:
= 表示默認值
:= 表示修改過的
【幾個特殊的XX參數(shù)】
-Xmx : JVM堆的最大值 -XX:MaxHeapSize 初始化是機器內存的1/4
-Xms : JVM堆的最小值 -XX:InitialHeapSize 初始化是機器內存的1/64
最佳實踐:調整為一樣的大小笨奠,防止內存抖動
調整 VM options : -Xms10m -Xmx10m
jinfo -flag InitialHeapSize pid
結果:初始堆大小
jinfo -flag MaxHeapSize pid
結果:最大堆大小
-Xss -XX:ThreadStackSize
jinfo -flag ThreadStackSize pid
User user = new User();
引用(棧) 對象(堆)
User.class(metaspace)
一流的企業(yè)做規(guī)范
二流企業(yè)做產品
三流企業(yè)做產品
四流企業(yè)做服務
五流企業(yè)做項目
5個異常
5個JVM參數(shù)
----------------------------------------------------華麗分割線---------------------------------------------------
選用合適的垃圾回收器很重要
開啟ccs就是短指針
每new 一個對象袭蝗,都會有一個指向自己class的指針,class是在metaspace里面
默認是64位的長指針般婆,考慮性能到腥,可以修改為32位的短指針
【jstat -gc pid 】
打出常用用法: jstat -options
demo:
調整 VM options: -Xms128m -Xmx128m -XX:MetaspaceSize=128m -XX:+UseCompressedClassPoint
jstat -gc pid
結果:關注 CCSC CCSU 是有值的 再就是關注MC MU :metaspace 總共大小,用掉的大小
調整 VM options: -Xms128m -Xmx128m -XX:MetaspaceSize=128m -XX:-UseCompressedClassPoint
jstat -gc pid
結果:關注 CCSC CCSU 均為0腺兴,關閉ccs,就不存在ccs的概念了左电,64位的就是存在metaspace 里面, 這時候再就是關注MC MU页响,MC = MC(上面) + CCSC(上面)
調整 VM options: -Xms128m -Xmx128m -XX:MetaspaceSize=128m -Xint -XX:-UseCompressedClassPoint
即:默認是comp 編譯執(zhí)行代碼篓足,這里修改為解析執(zhí)行
jstat -gc pid
結果:關注,MC 闰蚕,會發(fā)現(xiàn)比默認的編譯執(zhí)行 總的元空間小
----------------------------------------------------華麗分割線---------------------------------------------------