1. 求《JVMG1源碼分析和調優豆瓣》全文免費下載百度網盤資源,謝謝~
《JVM G1源碼分析和調優豆瓣》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/1i8sXLpI7Ey-07u7mGCq2WA
2. jvm源碼精析 怎麼都是cpp
Attach是什麼
在講這個之前,我們先來點大家都知道的東西,當我們感覺線程一直卡在某個地方,想知道卡在哪裡,首先想到的是進行線程mp,而常用的命令是jstack ,我們就可以看到如下線程棧了
2014-06-18 12:56:14
Full thread mp java HotSpot(TM) 64-Bit Server VM (24.51-b03 mixed mode):
"Attach Listener" daemon prio=5 tid=0x00007fb0c6800800 nid=0x440b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Service Thread" daemon prio=5 tid=0x00007fb0c584d800 nid=0x5303 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007fb0c482e000 nid=0x5103 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007fb0c482c800 nid=0x4f03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007fb0c4815800 nid=0x4d03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007fb0c4813800 nid=0x3903 in Object.wait() [0x00000001187d2000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aaa85568> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x00000007aaa85568> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
"Reference Handler" daemon prio=5 tid=0x00007fb0c4800000 nid=0x3703 in Object.wait() [0x00000001186cf000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aaa850f0> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x00000007aaa850f0> (a java.lang.ref.Reference$Lock)
3. JVM_位元組碼文件(ClassFile)詳解
我們知道 javac 命令可以將 .java 文件編譯成 .class 文件,而這個 Class 文件 中包含了 Java虛擬機 指令集、符號表以及若干其他輔助信息;最終將在 Java虛擬機 運行。
本文是以 JVM8 為例的。
每一個 Class文件 都有如下的 ClassFile 文件結構:
先簡單介紹一下 ClassFile 文件結構各部分含義:
描述符是表示欄位或方法類型的字元串。
欄位描述符表示類、實例或局部變數的類型。
從上面文法可以看出,欄位描述符中一共有三個類型:
方法描述符包含 0 個或者多個參數描述符以及一個返回值描述符。
看了描述符,可能大家有點疑惑,泛型信息怎麼表示啊?
常量池的通用格式如下:
目前 JVM8 中一共用 14 種常量類型,分別如下:
我們知道要使用一個欄位或者調用一個方法,就必須知道欄位或者方法所屬類符號引用,和欄位的名字和類型,方法的名字和方法參數類型以及方法返回值類型。
但是我們知道類是能繼承的,那麼子類調用父類的方法或者欄位,這里的所屬類符號引用,到底是子類本身還是父類的呢?
我們知道類,方法,欄位都有不同的訪問標志,在 Class 文件 中使用一個 u2 類型數據項來存儲,也就是最多可以有 16 個不同標志位。
在類,方法,欄位中有相同的標志,也有不同的標志,總體規劃,我們可以藉助 Modifier 類的源碼來了解:
在 Modifier 類中,類的訪問標志:
我們知道在 java 中類可以用的修飾符有: public , protected , private , abstract , static , final , strictfp 。
但是我們再看 Class 文件 中類的訪問標志:
仔細看,你會發現有些不同點:
在 Modifier 類中,欄位的訪問標志:
我們知道在 java 中欄位可以用的修飾符有: public , protected , private , static , final , transient 和 volatile 。
但是我們再看 Class 文件 中欄位的訪問標志:
Class 文件 中欄位的訪問標志和 java 中欄位的修飾符差不多,只是多了 ACC_SYNTHETIC 和 ACC_ENUM 兩個標志。
在 Modifier 類中,方法的訪問標志:
我們知道在 java 中方法可以用的修飾符有:
public , protected , private , abstract , static , final , synchronized , synchronized 和 strictfp 。
但是我們再看 Class 文件 中方法的訪問標志:
欄位詳情 field_info 的格式如下:
方法詳情 method_info 的格式如下:
關於 Class 文件 中屬性相關信息,我們再後面章節介紹。
我們可以通過 javap 的命令來閱讀 Class 文件 中相關信息。
這個是最簡單的一個類,沒有任何欄位和方法,只繼承 Object 類,我們來看看它編譯後的位元組碼信息,通過 javap -p -v T.class 的命令:
我們重點關注常量池相關信息,會發現雖然 T.class 很乾凈,但是也有 15 個常量,來我們依次分析:
與之前的例子相比較,多了一個欄位和方法,那麼得到的位元組碼信息如下:
但是你會發現常量池中怎麼沒有這個欄位 name 的 CONSTANT_Fieldref_info 類型的常量呢?
那是因為我們沒有使用這個欄位。
多寫了一個方法 test1 來調用 name 欄位和 test 方法,那麼得到的位元組碼信息如下:
這里定義一個父類 TParent ,有一個公共欄位 name 和方法 say 。子類
4. jvm 基礎篇-(4)-對象動態年齡計算規則
還沒達到,大牛程度,可以看源碼,看動態計算對象年齡的程度呦~
-XX:MaxTenuringThreshold=X X默認是15,15的含義是從eden-->survivor 對象年齡+1,survivor-->eden 對象年齡+1,直到年齡達到15後開始進入old Generation。
Hotspot遍歷所有對象時, 按照年齡從小到大對其所佔用的大小進行累積,當累積的某個年齡大小超過了survivor區的一半時,取這個年齡和MaxTenuringThreshold中更小的一個值,作為新的晉升年齡閾值。
eg:
eg:Survivor區 = 64M,desired survivor = 32M,此時Survivor區中age<=2的對象累計大小為41M,41M大於32M,所以晉升年齡閾值被設置為2,下次Minor GC時將年齡超過2的對象被晉升到老年代。就會導致old generation 快速填滿,觸發old gc(old gc 有三處STW),所以這是建議調整 -XX:SurvivorRatio 參數。
1、如果固定按照MaxTenuringThreshold設定的閾值作為晉升條件: a)MaxTenuringThreshold設置的過大,原本應該晉升的對象一直停留在Survivor區,直到Survivor區溢出,一旦溢出發生,Eden+Svuvivor中對象將不再依據年齡全部提升到老年代,這樣對象老化的機制就失效了。 b)MaxTenuringThreshold設置的過小,「過早晉升」即對象不能在新生代充分被回收,大量短期對象被晉升到老年代,老年代空間迅速增長,引起頻繁的Major GC。分代回收失去了意義,嚴重影響GC性能。
2、相同應用在不同時間的表現不同:特殊任務的執行或者流量成分的變化,都會導致對象的生命周期分布發生波動,那麼固定的閾值設定,因為無法動態適應變化,會造成和上面相同的問題。
總結來說,為了更好的適應不同程序的內存情況, 虛擬機並不總是要求對象年齡必須達到Maxtenuringthreshhold再晉級老年代 。
傳送門 jvm-對象年齡(-XX:+PrintTenuringDistribution)
5. 急求深入理解Java虛擬機JVM高級特性與最佳實踐 源碼
這方面的書我倒是沒有看過 ,但是我看過一半的 java 。。。。編程思想 挺不錯 很厚 講java 講的很到位 那本書適合 開發2-4年java程序員看 我推薦你看下 對要是找到 關於java虛擬機的 源碼和高級特性 最好也給我一份 謝謝 研究研究
6. JVM-安全點
Total time for which application threads were stop 超級長時間,這行日誌代表什麼,以及為什麼時間會這么長
當GC發生時,每個線程只有進入了SafePoint才算是真正掛起,也就是真正的停頓,這個日誌的含義是整個GC過程中STW的時間,配置了 -XX:+PrintGCApplicationStoppedTime 這個參數才會列印這個信息。
重點: 第一個 2.81 seconds 是JVM啟動後的秒數,第二個 2.6 seconds 是 JVM發起STW的開始到結束的時間。特別地,如果是GC引發的STW,這條內容會緊挨著出現在GC log的下面。
有關安全點的詳細說明,請移步:
JVM源碼分析之安全點safepoint
[Java JVM] Hotspot GC研究- GC安全點 (Safepoint&Stop The World)
等待所有用戶線程進入安全點後並阻塞,做一些全局性操作的行為。
配置 -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 參數,虛擬機會列印如下日誌文件:
RevokeBias、BulkRevokeBias、偏向鎖取消情況。
Deoptimize、
G1IncCollectionPause GC GC 執行情況。
分析 -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 產生的日誌信息基本上STW的原因都是RevokeBias或者BulkRevokeBias。這個是撤銷偏向鎖操作,雖然每次暫停的 時間很短,但是特別頻繁出現也會很耗時。
一些高並發的系統中,禁掉JVM偏向鎖優化,可以提升系統的吞吐量 。禁用偏向鎖的參數為: -XX:-UseBiasedLocking
R大分析類似情況
調優建議
各種JVM參數說明
stw分析
R大的博客
安全點 stw說明
偏向鎖
7. 怎樣在ide中進行jvm源碼的調試
按照的方式配置好Mingw32,將其安裝至c:\mingw
將Insight解壓至c:\insight
'make clean',刪除所有的objs,重置編譯環境
'make SYMBOLS=1',編譯mame,別忘了符號編譯選項'SYMBOLS=1'
啟動C:\insight\bin\insight.exe
菜單File->Target Settings->Connection->Target,選擇'Exec'
在下面的ExecArguments裡面添上mame的命令行啟動參數,如ddragon2
File->Open,載入剛剛編譯好的mame.exe
Run->Run,啟動程序,然後便可以設置斷點、單步跟蹤了
8. JVM原理是什麼
JVM工作原理和特點主要是指操作系統裝入JVM是通過jdk中Java.exe來完成,通過下面4步來完成JVM環境.
1.創建JVM裝載環境和配置
2.裝載JVM.dll
3.初始化JVM.dll並掛界到JNIENV(JNI調用介面)實例
4.調用JNIEnv實例裝載並處理class類。
9. JVM源碼分析之一個Java進程究竟能創建多少線程
線程大家都熟悉,new Thread().start()即會創建一個線程,這里我首先指出一點new Thread()其實並不會創建一個真正的線程,只有在調用了start方法之後才會創建一個線程,這個大家分析下Java代碼就知道了
Thread的構造函數是純Java代碼,start方法會調到一個native方法start0里,而start0其實就是JVM_StartThread這個方法!
10. 簡述jvm工作原理
Java是一種技術,它由四方面組成:Java編程語言、Java類文件格式、Java虛擬機和Java應用程序介面(Java API)。
運行期環境代表著Java平台,開發人員編寫Java代碼(.java文件),然後將之編譯成位元組碼(.class文件),再然後位元組碼被裝入內存,一旦位元組碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。
Java平台由Java虛擬機和Java應用程序介面搭建,Java語言則是進入這個平台的通道,用Java語言編寫並編譯的程序可以運行在這個平台上。
在Java平台的結構中, 可以看出,Java虛擬機(JVM) 處在核心的位置,是程序與底層操作系統和硬體無關的關鍵。它的下方是移植介面,移植介面由兩部分組成:適配器和Java操作系統, 其中依賴於平台的部分稱為適配器;JVM 通過移植介面在具體的平台和操作系統上實現;在JVM 的上方是Java的基本類庫和擴展類庫以及它們的API, 利用Java API編寫的應用程序(application) 和小程序(Java applet) 可以在任何Java平台上運行而無需考慮底層平台, 就是因為有Java虛擬機(JVM)實現了程序與操作系統的分離,從而實現了Java 的平台無關性。
JVM在它的生存周期中有一個明確的任務,那就是運行Java程序,因此當Java程序啟動的時候,就產生JVM的一個實例;當程序運行結束的時候,該實例也跟著消失了。下面我們從JVM的體系結構和它的運行過程這兩個方面來對它進行比較深入的研究。
1、Java虛擬機的體系結構
·每個JVM都有兩種機制:
①類裝載子系統:裝載具有適合名稱的類或介面
②執行引擎:負責執行包含在已裝載的類或介面中的指令
·每個JVM都包含:
方法區、Java堆、Java棧、本地方法棧、指令計數器及其他隱含寄存器
2、Java代碼編譯和執行的整個過程
也正如前面所說,Java代碼的編譯和執行的整個過程大概是:開發人員編寫Java代碼(.java文件),然後將之編譯成位元組碼(.class文件),再然後位元組碼被裝入內存,一旦位元組碼進入虛擬機,它就會被解釋器解釋執行,或者是被即時代碼發生器有選擇的轉換成機器碼執行。
(1)Java代碼編譯是由Java源碼編譯器來完成,也就是Java代碼到JVM位元組碼(.class文件)的過程。
2)Java位元組碼的執行是由JVM執行引擎來完成
Java代碼編譯和執行的整個過程包含了以下三個重要的機制:
·Java源碼編譯機制
·類載入機制
·類執行機制
(1)Java源碼編譯機制
Java 源碼編譯由以下三個過程組成:
①分析和輸入到符號表
②註解處理
③語義分析和生成class文件
最後生成的class文件由以下部分組成:
①結構信息:包括class文件格式版本號及各部分的數量與大小的信息
②元數據:對應於Java源碼中聲明與常量的信息。包含類/繼承的超類/實現的介面的聲明信息、域與方法聲明信息和常量池
③方法信息:對應Java源碼中語句和表達式對應的信息。包含位元組碼、異常處理器表、求值棧與局部變數區大小、求值棧的類型記錄、調試符號信息
(2)類載入機制 JVM的類載入是通過ClassLoader及其子類來完成的