《Java Performance》筆記4——JVM效能調優入門
1.應用程式的系統需求:
應用程式的系統需求是應用程式執行時某方面的要求,譬如吞吐量、響應時間、記憶體消耗量、可用性、可管理性等。JVM效能調優主要針對如下的系統需求:
(1).可用性:
是對應用程式處於可操作、可使用狀態的度量。可用性需求指的是當程式的某些元件發生故障或失效時,應用程式或應用程式的一部分在多大程度上海可以繼續提供服務。
Java應用程式的上下文中,利用應用程式元件化、在多個JVM中執行或在多個JVM上執行多個應用程式例項都可以實現高可用性。強調高可用性的代價之一是管理成本的增加,引入更多的JVM意味著要管理更多的JVM,從而導致複雜性增加以及隨之而來的管理成本。
(2).可管理性:
可管理性是對由執行、監控應用程式而產生的操作性開銷的度量,同時也包含了配置應用程式的難易程度。可管理性需求用於衡量系統管理的難易程度。
(3).吞吐量:
吞吐量是堆單位時間內處理工作量的度量。設計吞吐量需求時,一般不考慮它對延遲或者響應時間的影響。
通常情況下,增加吞吐量的代價是延遲的增加或者記憶體使用的增加。
(4).延遲及響應性:
延遲或者響應性是指應用程式收到指令開始工作直到完成該工作所消耗時間的度量。
定義延遲及響應性需求時,一般不考慮程式吞吐量,通常情況下,提高響應性或縮小延遲的代價是更低吞吐量、或者更多的記憶體消耗(或者二者同時發生)。
(5).記憶體佔用:
記憶體佔用是指在同等程度的吞吐量、延遲、可用性和可管理性前提下,執行應用程式所需的記憶體大小。
記憶體佔用通常以執行應用程式所需的java堆大小或者執行應用程式所需的總記憶體大小來表述。一般情況下,通過增大java堆的方式增加可用記憶體能夠提供吞吐量、降低延遲或者兼顧二者。
(6).啟動時間:
啟動時間是應用程式初始化所消耗時間。此外,java應用程式中另一個值得關注的指標是現代JVM完成應用程式熱區優化,初始化所消耗的時間。
Java應用程式初始化的完成時間取決於很多因素,包括(但不限於):初始化時載入的類的數量、需要初始化的物件的數量、這些物件如何初始化以及HotSpot VM的執行時環境選擇,即Client模式還是Server模式。
2.JVM部署模式選擇:
JVM部署模式的選擇是指將應用程式部署到單個
(1).單JVM部署模式:
將java應用部署在單個JVM上時,由於不需要管理多個JVM,可以降低管理成本,此外每個部署的JVM都有相應的記憶體開銷,使用單JVM避免了這部分資源使用,應用程式所消耗的總記憶體數量會減少。
單JVM部署模式存在單點故障,即當應用程式遭遇災難性錯誤或JVM失效時,無法保證應用程式的可用性。
另外,如果應用記憶體消耗超過了32位JVM處理能力時,需要使用64位JVM,需要確認所使用的第三方模組是否支援64位JVM,如果還使用了JNI,需要使用64位編譯器編譯。
(2).多JVM部署模式:
將java應用部署到多個JVM例項能夠獲得更好的可用性,以及更低延遲的可能性。採用多JVM部署模式時,單一應用程式或JVM例項的失效只會影響整個應用程式的部分功能。同時由於在多JVM部署模式下,java堆通常比較小,較小的堆在垃圾收集時產生的停頓更小,因此多JVM部署模式可能提供更低的延遲。另外,採用多JVM部署模式由於將負荷分發到多個JVM,能夠改善應用程式的擴充套件性,從而處理更高負荷,提供吞吐量。
3.JVM執行模式選擇:
(1).Client/Server模式:
A.Client模式:特點是啟動快、佔用記憶體少、JIT編譯器生成程式碼的速度也更快,但是JIT編譯優化的程式碼質量不如Server模式高。
B.Server模式:JIT編譯優化需要消耗額外的時間以收集更多的應用程式行為,啟動時間更長,但是能生成高度優化的機器碼。
C.Tiered Server模式:在JDK7中正式釋出,結合了Client和Server模式的優點,即快速啟動和高效的生成碼。如果使用的是java7或更新的版本的JVM,可以使用”-server -XX:+TieredCompilation”命令列選項啟動Tiered Server模式。
(2).32位/64位:
HotSpot VM預設使用32位執行模式,但是伺服器的硬體配置、第三方庫是否支援64位JVM以及JNI是否使用64位編譯也決定是否適合使用64位JVM。
A.32位JVM:
預設的HotSpot VM執行模式,java堆記憶體小於2G的推薦選擇。
B.64位JVM:
當java堆介於2G~32G時,使用”-d64 -XX:+UseCompressedOops”命令列選項的64位JVM。
當java堆大於32G時,使用”-d64”命令列選項的64位JVM。
注意:使用” -XX:+UseCompressedOops”命令列選項的HotSpot VM,最大java堆小於等於26G時效能最好,java6 Update18之後的HotSpot VM能根據最大java堆的情況自動啟用它。
(3).垃圾收集器選擇:
JVM的垃圾收集器選擇也影響著系統需求,HotSpot VM提供了多種垃圾收集器,很多情況下使用Throughput或CMS垃圾收集器就可以滿足系統對吞吐量、響應性等需求的要求。
4.垃圾收集器調優基礎:
(1).垃圾收集器調優的效能屬性:
A.吞吐量:
評價垃圾收集器的重要指標之一,指不考慮垃圾收集引起的停頓時間或記憶體消耗,垃圾收集器能支撐應用程式達到的最高效能指標。
B.延遲:
也是評價垃圾收集器能力的重要指標,度量標準是縮短由於垃圾收集引起的停頓時間或完全消除因垃圾收集所引起的停頓,避免應用程式執行時發生抖動。
C.記憶體佔用:
垃圾收集器流暢執行所需要的記憶體數量。
上述3個性能屬性的任何一個提高,都會對其他的一個或兩個效能屬性帶來損失,因此需要根據應用場景確定上述效能屬性的優先順序。
(2).垃圾收集器調優原則:
A.Minor GC回收原則:
每次Minor GC都儘可能多地收集垃圾物件,遵循這一原則可以減少Full GC的頻率,Full GC的持續時間總是最長的,是應用程式無法達到其延遲或吞吐量要求的罪魁禍首。
B.GC記憶體最大化原則:
處理吞吐量和延遲問題時,垃圾處理器能使用的記憶體越大,即java堆空間越大,垃圾收集的效果越好,應用程式執行也約流暢。
C.GC調優的3選2原則:
在三個效能屬性(吞吐量、延遲和記憶體佔用)中任意選擇兩個進行JVM垃圾收集器調優。
5.確定記憶體佔用:
(1).計算活躍資料大小:
活躍資料的大小是指,應用程式穩定執行時,長期存活物件所佔用的java堆記憶體量,即它是應用程式運行於穩定態時,Full GC之後java堆佔用的空間大小(包括老年代活躍資料和永久代活躍資料)。活躍資料大小是確定執行應用程式所需java堆大小的切入點。
為了更好度量應用程式的活躍資料大小,最好在多次Full GC之後在檢視java堆佔用情況,另外,需要確保Full GC發生時,應用程式正處於穩定態。
對於發生Full GC或者不經常發生Full GC的應用程式來說,可以使用JConsole、VisualVM或者jmap(需要使用”jmap -histo:live PID”命令)人工觸發Full GC。
(2).初始堆空間大小配置:
通過計算活躍資料大小之後,下面是初始堆空間大小配置的通用原則:
A.java堆:
使用-Xmx和-Xms將java堆初始大小設定為老年代活躍資料大小的3~4倍。
B.永久代:
使用-XX:PermSize和-XX:MaxPermSize將永久代初始大小設定為永久代活躍資料大小的1.2~1.5倍。
C.新生代:
使用-Xmn將新生代初始大小設定為老年代活躍資料大小的1~1.5倍。
D.老年代:
老年代空間大小=java堆-新生代大小,老年代應設定為老年代活躍資料大小的2~3倍。
6.調優延遲/響應性:
(1).確定延遲/響應性系統要求:
A.應用程式可接受的平均停滯時間。
B.應用程式可接受的Minor GC(會導致延遲)頻率。
C.應用程式可接受的最大停頓時間。
D.應用程式可接受的最大停頓發生頻率。
(2).評估垃圾收集對延遲/響應性影響因素:
A.測量Minor GC的持續時間。
B.統計Minor GC的頻率。
C.測量Full GC的最差(最長)持續時間。
D.統計最差情況下,Full GC的頻率。
(3).優化新生代大小:
Minor GC需要的時間及頻率與新生代密切相關,通常情況下,新生代空間越小,Minor GC的持續時間越短,但是Minor GC的頻率會越大;新生代空間越大,Minor GC的發生頻率越低,但是Minor GC的持續時間越長。
調整新生代空間的原則:
A.老年代空間:
老年代空間大小不應該小於老年代活躍資料大小的1.5倍,在因調整Minor GC持續時間和頻率而調整新生代大小時,要確保老年代大小保持不變,即同步調整java堆和新生代大小。
B.新生代空間:
新生代空間至少應為java堆大小的10%。
C.java堆空間:
java堆空間大小不要超過JVM可用實體記憶體。
(4).優化老年代大小:
發生於穩定態的Full GC持續時間是應用程式的最差Full GC持續時間,Full GC的時間間隔是最差Full GC頻率。
調整老年代大小原則:
A.調整老年代大小時,確保新生代大小保持不變,即同步調整java堆大小和老年代大小。
B.Full GC頻率的預估應該依據物件的提升率進行計算:
物件提升率是物件從新生代複製到老年代物件的比率,計算方法如下:
首先,觀察Full GC之前的連續多個Minor GC中老年代空間佔用。
其次,計算相鄰Minor GC老年代空間佔用。
第三,計算Minor GC物件平均提升速度=相鄰Minor GC老年代空間佔用/Minor GC間隔時間。
第四,估算Full GC頻率=老年代剩餘空間/Minor GC物件平均提升速度。
7.CMS調優延遲/響應性:
CMS垃圾收集器中Stop-The-World的壓縮式GC與Full GC有細微區別:若老年代沒有足夠空間處理來自新生代的物件晉升即老年代溢位,則只會在老年代觸發一次Stop-The-World的壓縮式GC;發生Full GC時,觸發使用了-XX:-ScavengeBeforeFullGC命令列選項,否則老年代和新生代都會進行垃圾收集。
由於Stop-The-World的壓縮式GC對老年代空間進行壓縮,耗時比較長,因此調優CMS收集器的目的是避免Stop-The-World的壓縮式GC。
(1).呼叫新生代的Survivor空間:
HotSpot VM的新生代空間通常分為三部分:Eden、Survivor From和Survivor To,其中Survivor From和Survivor To是相互互換的,新分配的物件通常存放在Eden和Survivor From中,Minor GC之後存活的物件會存放在Survivor To中,合適大小的Survivor空間可以使得Minor GC回收最多垃圾物件,避免短期物件晉升到老年代,增加老年代碎片。
A.Survivor空間的大小:
可以通過-XX:SurvivorRation=<ration>選項來控制,
Survivor空間大小=-Xmn<value>/(-XX:SurvivorRation=<ration>+2)。
B.Survivor空間調整:
對於給定新生代,減少Survivor比率會增大Survivor空間,同時減少Eden空間,導致更頻繁的Minor GC,即垃圾收集的頻率越高,物件老化的速度越快;增大Survivor比率會減少Survivor空間,同時增大Eden空間,減少Minor GC頻率,即垃圾收集的頻率越低,物件老化的速度越慢。
C.調整Survivor空間原則:
若可以增加Minor GC頻率,可以減少一部分Eden空間來增大Survivor空間;若記憶體足夠,最好增加新生代大小,保持Eden空間恆定的同時增加Survivor空間。
調整Survivor空間要和監控物件晉升年齡閥值一起配合。
(2).調整物件晉升年齡閥值:
一個物件的年齡是它所經歷的Minor GC次數,新生代空間中年齡大於晉升閥值的物件都會被從新生代提升到老年代空間,即晉升年齡閥值決定了物件在新生代Survivor空間保留的時間。
新生代中的有效物件老化可以避免將不成熟的物件提升到老年代空間,減少了老年代空間的佔用率增長,同時也降低了CMS垃圾收集器的執行頻率,減少了可能的老年代空間碎片。
A.監控物件晉升年齡閥值:
使用-XX:+PrintTenuringDistribution選項可以監控物件晉升的釋出或物件年齡釋出,輸出結果如下:
Desired survivor size 3506176 bytes, new threshold 1 (max 15)
- age 1: 7012344 bytes, 7012344 total
從上面輸出可以看出來預設的晉升閥值為15,由(max 15)標識;通過new threshold 1 可以知道虛擬機器內部計算出的晉升閥值為1;Desired survivor size 3506176 bytes是Survivor空間大小乘以目標存活率(由-XX:TargetSurvivorRation=<percent>選項控制,預設是50)得到的空間大小;- age 1: 7012344 bytes, 7012344 total是每個年齡段物件及其佔用的空間大小單獨列為一行。
由上面例子看出期望的Survivor空間3506176 bytes遠小於存活物件大小7012344 bytes,導致Survivor空間溢位,從而使得Minor GC將一些物件提升到老年代。
觀察到Survivor空間過小時,調整Survivor空間大小,使得總存活物件小於等於期望的Survivor空間大小,同時使得晉升閥值等於最大晉升閥值。
B.調整物件晉升年齡閥值:
使用-XX:MaxTenuringThreshold=<n>選項指定HotSpot VM物件年齡最大晉升閥值,當目標Survivor空間的佔用小於等於HotSpot VM期望維護的值時,HotSpot VM將使用最大的晉升閥值作為其計算出的晉升閥值;當目標Survivor空間的佔用大於HotSpot VM期望維護的值時,HotSpot VM將使用計算出的低於最大閥值的晉升閥值來保證目標Survivor空間的佔用。
設定原則:
不建議將其設定為0,這會造成剛剛分配的物件在隨後的Minor GC中直接從新生代提升到老年代,引起老年代空間迅速增長,導致頻繁的Full GC;
也不建議將其設定為遠大於實際可能的最大值,這會造成物件長期存在於Survivor空間,直到最後Survivor空間溢位,一旦Survivor空間溢位,物件將被全部提升至老年代,不再依據其實際年齡進行提升,導致短期物件在長期物件之前被提升至老年代,嚴重影響物件老化機制的有效性。
(3).呼叫老年代空間佔用率:
CMS的新生代空間和晉升年齡閥值調整好之後,就可以保證大部分垃圾物件在Minor GC時被回收,同時保證物件有效老化,即老年代空間佔用率增長可控,接下來就是要調整老年代空間佔用率,以確保避免老年代發生Stop-The-World的壓縮式GC。
成功的CMS收集器效能調優要能以物件從新生代提升到老年代的同等速度對老年代物件進行垃圾收集,達不到這個標準則稱之為”失速”(Lost the race),失速的結果就會發生Stop-The-World的壓縮式GC。避免失速的關鍵是要結合足夠大的老年代空間和足夠快地初始化CMS垃圾收集週期,讓它比提升速率更快的速度回收空間。
CMS週期的初始化週期基於老年代空間佔用情況,如果CMS開始的太晚,就會發生失速;但是如果CMS週期啟動的太早,又會引起無用的消耗,影響應用程式的吞吐量。
HotSpot VM會嘗試自適應第計算在空間佔用多大時開啟CMS收集週期,但是做的並不理想,某些情況下無法避免會出現Stop-The-World的壓縮式GC,通過在GC日誌中查詢併發模式失效(Concurrent Mode Failure)定位Stop-The-World的壓縮式GC,如果發生Stop-The-World的壓縮式GC,可以使用如下方式配置老年代空間佔用率以啟動CMS週期:
A.-XX:CMSInitiatingOccupancyFraction=<percent>:
設定的值是CMS垃圾收集週期在老年代空間佔用達到多少百分比時啟動,僅在第一個CMS週期中使用設定的比率,之後週期又轉為自適應啟動CMS週期。
設定的原則為至少應該是老年代活躍資料大小的1.5倍。
B.-XX:+UseCMSInitiatingOccupancyOnly:
與-XX:CMSInitiatingOccupancyFraction=<percent>選項一起使用,告知HotSpot VM總是使用-XX:CMSInitiatingOccupancyFraction=<percent>設定的比率作為啟動CMS週期的閥值。
(4).調優CMS對永久代收集:
Full GC也可能源於永久代空間用盡,通過監控GC日誌,可以判斷Full GC是否由永久代耗盡引起。
在CMS中,HotSpot VM預設情況下不會對永久代空間進行垃圾收集,通過以下的命令列選項,可以控制CMS對永久代的收集:
A.開啟CMS對永久代的垃圾收集:
-XX:+CMSClassUnloadingEnabled,Java6 Update3或更新的版本,還可以使用-XX:+CMSPermGenSweepingEnabled與-XX:+CMSClassUnloadingEnabled一起配合使用。
B.調整永久代佔用空間:
和老年代類似,開啟CMS對永久代垃圾收集之後,也可以通過設定永久代空間佔用,來控制CMS在永久代的垃圾收集,引數如下:
-XX:CMSInitiatingPermOccupancyFraction=<percent>:
指定永久代空間佔用率達到多少百分比時啟動CMS在永久代垃圾收集,僅在僅在第一個CMS週期中使用設定的比率,之後週期又轉為自適應啟動CMS週期。
-XX:+UseCMSInitiatingOccupancyOnly:
與-XX:CMSInitiatingPermOccupancyFraction=<percent>一起配合使用,告知HotSpot VM總是使用-XX:CMSInitiatingPermOccupancyFraction=<percent>設定的比率作為啟動CMS週期的閥值。
(5).調優CMS停頓時間:
CMS週期中有兩個階段是Stop-The-World的階段:初始標記和重新標記,處於這兩個階段的應用程式會被阻塞,雖然初始標記是單執行緒的,卻極少佔很長的時間,通常情況下遠小於其他的垃圾收集停頓,重新標記是多執行緒的,可以通過下面的HotSpot VM命令列選項控制:
A.-XX:ParallelGCThreads=<n>:
控制重新標記階段使用的執行緒數,若Runtime.getRuntime().availableProcessors()的返回值小於等於8,則預設等於這個值;否則,該預設值=8+(Runtime.getRuntime().availableProcessors() - 8) * 5 / 8。
多個應用程式運行於同一系統的情況下,建議將其設定的小於預設值,否則由於大量的垃圾收集執行緒同時執行,應用程式效能會受到極大的影響。
B.-XX:+CMSScavengeBeforeRemark:
強制HotSpot VM在進入CMS重新標記階段之前先進行一次Minor GC,減少引用老年代空間的新生代物件數目,減少重新標記階段的工作量。
C.-XX:+ParallelRefProcEnabled:
如果應用程式有大量的引用物件或可終結物件要處理,使用該命令列選項可以減少垃圾收集的持續時間。
8.吞吐量調優:
(1).CMS吞吐量調優:
CMS吞吐量調優與其延遲調優類似,簡單原則如下:
A.增加新生代大小,降低Minor GC頻率。
B.增加老年代大小,降低CMS週期頻率並減少記憶體碎片,從而減少併發模式失效以及Stop-The-World的壓縮式GC發生機率。
C.調整新生代中Eden和Survivor空間大小以優化物件老化,減少由新生代提升到老年的物件數目,最終減少CMS週期發生數。
D.優化CMS週期啟動條件,通過調整老年代和永久代空間佔用,儘可能晚啟動CMS週期。
CMS吞吐量調優的指導原則是CMS包括Minor GC所帶來的開銷應該小於10%,儘可能將開銷降低到1%~3%。
(2).Throughput吞吐量調優:
Throughput收集器是以吞吐量最優為目標的垃圾收集器,對於其吞吐量調優的目標是儘可能避免發生Full GC,或者更理想的情況下是在穩定態時永遠不要發生Full GC。
Throughput收集器預設啟用了一個稱為自適應大小調整的特性,根據物件分配以及存活率自動地對新生代的Eden和Survivor空間進行調整以最優化物件老化頻率。自適應調優既易於JVM調優,又達到足夠的吞吐量,可以滿足絕大多數應用程式的要求,對於一些需要竭盡全力提高吞吐量的應用,可以通過如下方式禁用自適應而手動調整Eden和Survivor空間大小:
A.-XX:-UseAdaptiveSizePolicy:
該命令選項用於禁用自適應大小調整特性,只對Throughput收集器有效。
禁用它將會犧牲改變應用程式行為的靈活性。
B.-XX:+PrintAdaptiveSizePolicy:
該命令選項用於列印Survivor空間佔用日誌,通常與XX:+PrintGCDetails 、-XX:+PrintGCDateStamps或-XX:+PrintGCTimeStamps等命令列選項一起配合使用,監控GC日誌中Survivor空間佔用情況,為手動調整Eden和Survivor空間大小提供依據,例子如下:
2015-05-20T11:01:59.507+0800: [GCAdaptiveSizePolicy::compute_survivor_space_size_and_thresh:
survived: 651584
promoted: 1622112
overflow: true
[PSYoungGen: 4160K->636K(4800K)]
4160K->2220K(15744K), 0.0057260 secs]
[Times: user=0.00 sys=0.00, real=0.01 secs]
GCAdaptiveSizePolicy標籤表明GC日誌是以-XX:+PrintAdaptiveSizePolicy選項開啟的。
Survived標籤後面的651584是Survived To空間中存活物件大小。
Promoted標籤後面的1622112是由新生代提升至老年代空間的物件大小。
Overflow標籤表明是否Survived空間溢位,即有新生代物件提升至老年代空間。
通過對Throughput收集器的Survivor空間不斷調整和監控,設定合理的Survivor空間大小,使得穩定執行的應用程式儘可能少地發生Survivor空間溢位。
Throughput收集器調優原則是垃圾收集器的開銷應該小於5%,如果可以將垃圾收集器的開銷減少到1%甚至更少,就達到極限了。
(3).NUMA系統上調優:
NUMA系統是非一致性記憶體架構,支援NUMA的JVM會根據NUMA節點劃分堆,執行緒建立物件時,只會在該執行緒所在核的NUMA節點上分配物件,後續該執行緒如果需要使用這個物件,就直接從本地記憶體中訪問,因此可能會發生跨CPU和跨記憶體節點訪問。通常情況下,如果沒有使用命令(RHEL下使用numactl)設定CPU親和性(Affinity),預設就跨多個記憶體節點。
如果跨CPU或記憶體節點訪問,HotSpot為Throughput收集器提供-XX:+UseNUMA選項,根據CPU與記憶體位置的關係在分配執行緒執行的本地記憶體中分配物件。
9.其他優化策略:
(1).實驗性(最近最大)優化:
新的效能優化整合到HotSpot VM時,常常首先在命令列選項-XX:+AggressiveOpts中引入,如果新的優化選項經過證明足夠穩定,就會被加入到預設配置中,如果應用程式的效能要求高於穩定性要求,可以嘗試啟用實驗性優化。
(2).逃逸分析:
逃逸分析(Escape Analysis)是一種評估java物件可見範圍的技術,若由某個執行緒建立的java物件在另一個執行緒中可以訪問,就被稱之為該物件逃逸了,若java物件不發生逃逸,就可以使用其他方法進行調優,這種優化技術被稱為逃逸分析。
HotSpot VM使用-XX:+DoEscapeAnalysis命令選項開啟逃逸分析(在Java6 Update23之後預設開啟),藉助逃逸分析,JIT編譯器可以做如下優化:
A.物件展開:在可能直接回收的空間而非java堆上分配物件欄位,例如物件欄位可以直接存放在CPU暫存器中,或者直接在棧上而不是java堆上分配物件。
B.標量替換:減少記憶體訪問的優化技術,把java物件拆散為基本型別的欄位直接在CPU暫存器中分配,減少記憶體訪問次數。
C.棧上分配:線上程的棧幀上而非java堆中分配物件,減少垃圾收集頻率。
D.消除同步:若執行緒分配的物件不會發生逃逸,且該執行緒持有該物件上的鎖,由於其他執行緒不會訪問該物件,因此可以通過JIT編譯器移除鎖。
E.消除垃圾收集的讀/寫屏障:只有執行緒分配的物件在另一執行緒中被訪問時才需要讀/寫屏障,若該物件只能由執行緒本地的根節點訪問,則在其他物件中儲存其地址時不需要執行讀/寫屏障。
(3).偏向鎖:
偏向鎖是偏向於最後獲得物件鎖執行緒的優化技術,即當一個執行緒剛剛獲得物件鎖,當下一次再獲取該物件鎖時HotSpot認為該執行緒還能獲取成功而直接把物件鎖交予該執行緒的一種優化技術,當只有一個執行緒鎖定該物件,沒有鎖衝突的情況下,其鎖開銷可以解決無鎖。
偏向鎖對於大多數應用效能提高很多,可以使用-XX:+UseBiasedLocking開啟偏向鎖(在JDK中預設開啟);但對於有鎖切換的應用,效能並不理想,可以使用-XX:-UseBiasedLocking關閉偏向鎖。
建議分別測量開啟和關閉偏向鎖情況下的應用效能,再決定是否關閉偏向鎖優化。
(4).大頁面記憶體支援:
計算機系統中的記憶體被劃分成稱為頁的固定大小的塊,程式訪問記憶體的過程中會將虛擬記憶體地址轉換為實體記憶體地址,這一轉換過程通常是通過頁表來完成的。遍歷頁表的代價通常比較高,為了減少每次記憶體訪問時訪問頁表的代價,通常使用一塊被稱為轉譯快查快取(TLB)的快速快取對虛擬地址到實體地址的轉換進行快取。TLB通常只能容納固定數量的條目,其每一條記錄就是按頁面大小統計的一塊記憶體地址區間的對映,因此,系統的記憶體頁面越大,每個條目能對映的記憶體地址區間越大,每個TLB
1.應用程式的系統需求:
應用程式的系統需求是應用程式執行時某方面的要求,譬如吞吐量、響應時間、記憶體消耗量、可用性、可管理性等。JVM效能調優主要針對如下的系統需求:
(1).可用性:
是對應用程式處於可操作、可使用狀態的度量。可用性需求指的是當程式的某些元件發生故障或失
龍果學院深入理解Java虛擬機器(Jvm效能調優+記憶體模型+虛擬機器原視訊
Java虛擬機器視訊教程一套不錯的視訊,課程一共有110課,課程目錄較多隻展示部分出來,喜歡的朋友下載看下
課程目錄(課程較多,只展示部分目錄)
課程大綱
第1節說在前面的話 [免費觀看]
Jinfo
檢視正在執行的Java應用程式的擴充套件引數
檢視jvm的引數
檢視java系統引數
Jstat
jstat命令可以檢視堆記憶體各部分的使用量,以及載入類的數量。命 ## 前言
首先給大家說聲對不起,最近屬實太忙了,白天上班,晚上加班,回家還要收拾家裡,基本每天做完所有事兒都是凌晨一兩點了,沒有精力再搞其他的了.
好了,進入正題,讓我們來聊聊JVM篇最後一個章節----JVM效能調優.童鞋們隨便開啟一個大廠的招聘崗位JD,應該都會有JVM調優相關的描述,其實招 https://blog.csdn.net/defonds/article/details/52598018
多次拉取 JStack,發現很多執行緒處於這個狀態: at jrockit/vm/Allocator.getNewTla(JJ)V(Native Method)
現實企業級Java開發中,有時候我們會碰到下面這些問題:
OutOfMemoryError,記憶體不足
記憶體洩露
執行緒死鎖
鎖爭用(Lock Contention)
Java程序消耗CPU過高
......
&n
來源:https://my.oschina.net/feichexia/blog/196575
現實企業級Java開發中,有時候我們會碰到下面這些問題:
OutOfMemoryError,記憶體不足
記憶體洩露
執行緒死鎖
鎖爭用(Lock Contention)
效能調優專題
效能優化如何理解
JVM調優
JAVA程式效能優化
Tomcat
Mysql
歡迎加入Java高階架構學習交流群:805685193 免費獲取Dubbo、Redis、設計模式、Netty、zookeeper、S
現實企業級Java開發中,有時候我們會碰到下面這些問題:
OutOfMemoryError,記憶體不足
記憶體洩露
執行緒死鎖
鎖爭用(Lock Contention)
Java程序消耗CPU過高
......
這
原文中的評論很有參考價值,轉發只是為了以後方便檢視
這是jvm優化系列第三篇:
JVM效能調優涉及到方方面面的取捨,往往是牽一髮而動全身,需要全盤考慮各方面的影響。但也有一些基礎的理論和原則,理解這些理論並遵循這些原則會讓你的效能調優任務將會更加輕鬆。為了更好的理解本 本文是《JVM 效能調優實戰之:一次系統性能瓶頸的尋找過程》 的後續篇,該篇介紹瞭如何使用 JDK 自身提供的工具進行 JVM 調優將 TPS 由 2.5 提升到 20 (提升了 7 倍),並準確定位系統瓶頸:我們應用裡靜態物件不是太多、有大量的業務執行緒在頻繁建立一些生命週期
1 叢集優化
儲存格式的選擇 ,https://www.infoq.cn/article/bigdata-store-choose
壓縮格式的選擇,https://www.ibm.com/develo
一、JVM記憶體模型及垃圾收集演算法
1.根據Java虛擬機器規範,JVM將記憶體劃分為:
New(年輕代)Tenured(年老代)永久代(Perm) 其中New和Tenured屬於堆記憶體,堆記憶體會從JVM啟動引數(-Xmx:3G)指定的記憶體中分配,Perm
tomcat的效能調優是實際生產中很重要的一部分,雖然我們平時在除錯時只要能跑起來就行,但是實際部署之後,當訪問的使用者量一增加,就涉及到tomcat的最大併發量等問題。那麼如何設定tomcat以及JVM,使我們的web應用的併發量增加呢?
一、tomcat記憶體
版本:JDK8
一、閱讀前熱身:
1、瞭解jvm啟動流程:
2、瞭解硬體、系統、程序三個層面的記憶體之間的概要記憶體分配,一張圖你就懂:
3、下面是需要背住的重點,敲黑板!!堆記憶體分配,想了解引數的可以到最下面看下備註和建議:
先來個日誌(看
如何在高效能伺服器上進行JVM調優?
為了充分利用高效能伺服器的硬體資源,有兩種JVM調優方案,它們都有各自的優缺點,需要根據具體的情況進行選擇。
採用64位作業系統,併為JVM分配大記憶體
我們知道,如果JVM中堆記憶體太小,那麼就會頻繁地發生垃圾回收
我, 一多年c++開發,由於專案原因需要對一個性能底下的多執行緒java程式進行調優,百度google了幾把,媽蛋,沒有發現指導如何java執行緒調優的文章啊,都是一些java使用規範,我去,那我大java的開發工程師都是怎麼調優的啊, 那我大C++工程師就帶領大家如何j
最近開始優化頁遊服務端的效能,一些心得總結一下。現在的伺服器硬體越來越好,幾十G記憶體,十幾個CPU。當硬體不是瓶頸的時候,如果讓程式發揮最大效用就成了我們需要考慮的問題。就遊戲伺服器來說,得滿足幾
玩過效能優化的朋友都清楚,效能優化的關鍵並不在於怎麼進行優化,而在於怎麼找到當前系統的效能瓶頸。效能優化分為好幾個層次,比如系統層次、演算法層次、程式碼層次...JVM 的效能優化被認為是底層優化,門檻較高,精通這種技能的人比較少。筆者呆過幾家技術力量不算弱的公司,每個公司內
轉載批註:最近因與別人討論問題時,問到JVM記憶體模型,但是苦於只知道JVM的大概內容,不知道詳細,也罷,近期會逐漸有充足的自己的時間,好好整理學習學習。以下內容為轉載別人的資料,個人認為寫的很好,就全文拷貝了。
===================華麗的分割線== 相關推薦
《Java Performance》筆記4——JVM效能調優入門
視訊:深入理解Java虛擬機器(jvm效能調優+記憶體模型+虛擬機器原理)共110集
深入理解Java虛擬機器(四)——JVM效能調優監控工具
【JAVA進階架構師指南】之五:JVM效能調優
ifeve.com 南方《JVM 效能調優實戰之:使用阿里開源工具 TProfiler 在海量業務程式碼中精確定位效能程式碼》
JVM效能調優監控工具jps、jstack、jstat、jmap、jinfo使用
JVM效能調優監控工具jps、jstack、jmap、jhat、jstat、hprof詳解
阿里資深架構師構造Java架構學習樹(效能調優+常用框架原始碼+微服務)
JVM效能調優監控工具jps、jstack、jmap、jhat、jstat、hprof使用詳解,以及例子
如何合理的規劃一次jvm效能調優
JVM 效能調優實戰之 使用阿里開源工具 TProfiler 在海量業務程式碼中精確定位效能程式碼
Spark SQL 筆記(17)—— 專案效能調優
JVM效能調優
tomcat與JVM效能調優
1分鐘帶你入門JVM效能調優
深入理解JVM——JVM效能調優實戰
java多執行緒程式效能調優 優化過程
遊戲伺服器JVM效能調優
JVM 效能調優實戰之:一次系統性能瓶頸的尋找過程
JVM記憶體模型,以及JVM效能調優