日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

性能监控/优化系列——JVM监控/调优

發布時間:2024/1/17 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 性能监控/优化系列——JVM监控/调优 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JVM監控

1.?ParNew表示CMS收集器在新生代采用多線程進行垃圾回收。DefNew表示順序垃圾收集器在新生代采用單線程進行垃圾回收。2.系統做完CMS cycle后,觀察minorGC的日志,如果日志中發現CMS收集前后的heap占用下降不明顯,那要么是已有的對象太少,以至于找到的unreachable對象很少,這樣浪費費CPU;要么是對象從新生代提拔到老生代的速率超過了CMS所能承受的范圍。總之,出現以上情況表示需要進行性能調優。3.?-XX:+CMSClassUnloadingEnabled?-XX:+CMSPermGenSweepingEnabledPermGen一般存放一些JVM的元數據(Class/反射代理等),比如Spring/Hibernate大量采用cglib,導致生成的Proxy會比較多,而這些都是存放在PermGen區域,默認情況下CMS不會去做回收,因此,為了保證PermGen空間正??梢栽O置以上兩個參數實現垃圾的回收。另外,-XX:CMSInitiatingPermOccupancyFraction=<percent>可以知道持久代的占用百分比。4. -XX:MaxTenuringThreshold=10,意思是說對象在survivor區域中經過10minorGC還存活的話就提拔到老生代。再比如?-XX:SurvivorRatio=65536?-XX:MaxTenuringThreshold=0這樣的配置實際上就是去掉了survivor區域,直接將對象從eden區域提拔到老生代。5. 在CMS中如果監控到它的兩個暫停階段initial mark or remark的暫停時間比一次minorGC的暫停時間還長,那么需要進行性能優化。6. 當fullGC發生時伴隨著持久代class的unload,那么需要考慮調大持久代空間的大小。Java代碼??
  • [Full?GC[Unloading?class?sun.reflect.GeneratedConstructorAccessor3]??
  • [Unloading?class?sun.reflect.GeneratedConstructorAccessor8]??
  • [Unloading?class?sun.reflect.GeneratedConstructorAccessor11]??
  • [Unloading?class?sun.reflect.GeneratedConstructorAccessor6]??
  • 8566K->5871K(193856K),?0.0989123?secs]??
  • 7. 使用jstack去挖掘鎖競爭的方法:Observing multiple thread stack traces trying to lock the same?lock address is an indication the application is experiencing lock contention,查看那些處在同一lock地址上的線程棧。?????8. JVM監控常用到的命令:-XX:+PrintGCDetails、-XX:+PrintGCTimeStamps、-XX:+PrintGCDateStamps、-Xloggc:<filename>、-XX:+PrintGCApplicationConcurrentTime?and -XX:+PrintGCApplicationStoppedTime。9.JVM監控常用的可視化工具:GCHisto、JConsole、jvisualvmJVM調優方法論1.The?client runtime?is specialized for rapid startup, small memory?footprint, and a JIT compiler with rapid code generation。The?server runtime?offersmore sophisticated code generation optimizations, which are more desirable in server?applications?,F在還出來一個新的runtime—tiered,但是還不成熟,tiered?combines the best of the client and server runtimes, that is, rapid startup?time and high performing generated code。2. 選擇JVM為32bit還是64bit取決于內存和第三方本地庫的使用,All?native components using the Java Native Interface (JNI) in a 64-bit JVM must be?compiled in 64-bit mode。3.?-XX:+UseParallelOldGC 和 -XX:+UseParallelGC的區別:前者會啟動新生代和老生代的多線程收集;而后者只啟動新生代的多線程收集,老生代是單線程的。4. 決定JVM性能的屬性:1. 吞吐量;2. 延時(latency);3.內存占用量5. JVM調優的三原則:1.?Minor GC Reclamation Principle—在minorGC時要最大化回收對象數;2.?GC Maximize?Memory Principle;3.?2 of 3 GC TuningPrinciple—調優點放在占總性能2/3的幾個屬性上:吞吐量/延時(latency)/內存占用量。6. 推薦的GC日志配置:-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:<filename>。?如果要調優為低延時,?-XX:+PrintGCApplicationStoppedTime(GC時應用暫停的時間)、-XX:+PrintGCApplicationConcurrentTime(GC時應用并發執行的時間)很有用。、推薦的log配置:7. ?當-Xmx 和-Xms不相同時,堆size可能會發生作自動調整,但是調整時,并不會調整新生代的大小。因此-Xmn只能用于-Xmx 和-Xms擁有相同值。事實上,把-Xmx 和-Xms設置為相同的值是一個好的習慣。8.?-XX:-ScavengeBeforeFullGC可以避免fullGC時收集新生代。9.?jmap -histo:live pid命令可以強制執行一次fullGC。10. GC時,以下因素影響到延時:1. 一次minorGC的持續時間;2. minorGC的頻率;3.?一次fullGC的持續時間;4. fullGC的頻率;1和2決定了是否需要重新定義young generation size。3和4決定了是否需要重新定義old generation size,及是否要啟用并發GC(-XX:+UseConcMarkSweepGC)。11. 可以通過像下面這樣的gclog來計算平均minorGC發生頻率和平均持續時間,如果發現平均平均持續時間〉期望的應用延時時間,那么就需要進一步調優:12. 當需要調優某一個代的size時,一般不要改變其他代的大小,而是通過調整堆堆和要調優的代的大小來實現。13. 關于各代size的大小,請關注以下guidelines:1)The old generation space size should be not be much smaller than 1.5x?the live data size。2)?Young generation space size should be at least 10% of the Java heap?size, the value specified as -Xmx and -Xms。3)When increasing the Java heap size, be careful not to exceed the?amount of physical memory available to the JVM。14. 提拔率的計算: rate=每秒提拔到老生代的數據量=每次minorGC提拔的數據量/收集頻率(s)=minorGC前后老生代空間占用量之差/收集頻率(s)。如果知道現在老生代剩余的空間(用y代表),那么就可以計算出可以算出多久后,這些剩余的空間會被提拔的對象占滿,公式為:m(s)=y/rate,這個m值就應該是fullGC的理想頻率。15. 對CMS的調優重點是:avoid a stop-the-world?compacting garbage collection。16. 從其它垃圾收集器轉到CMS時,一個常見的原則是擴大原有老生代20%-30%。17. 調優CMS要注意三個元素:提拔率、fragmentation(live對象之間的hole)、并發線程回收率。解決fragmentation的一種方法就是compacting?內存,但是會造成很大的延時(這個就是叫stop-the-world?),另一個解決方法是增大內存空間(使用Maximize Memory Principle),這不能完全解決fragmentation問題,但是能夠減少發生的頻率,最后一個方法是減低提拔率(這個可以使用Minor GC Reclamation Principle)。Survivor的調優:18.?survivor space計算公式:survivor space size = -Xmn<value>/(-XX:SurvivorRatio=<ratio> + 2)。19.?Tenuring Threshold的概念:每次minorGC時都會計算該值,看啥時能夠將一個對象提拔到老生代,它的值其實就是對象age(經歷的minorGC數),對象被分配時的age=0。如果某個時刻對象的age大于Tenuring Threshold就會被提拔到老生代。事實上,-XX:MaxTenuringThreshold=<n>命令可以指定這個值(該值的范圍:ranging from 0–15 for Java 5 Update 6 and later, 0–31?for Java 5 Update 5 and earlier),default maximum value=15。20. 如果需要Tenuring Threshold監控的值,可以通過下面命令啟動-XX:+PrintTenuringDistribution。下面是日志格式,其中,Desired survivor?size 8388608 bytes的值=一個survivor大小*target?survivor ratio(target survivor space occupancy,默認值為50%)。要保證survivor能夠容納16690480 total的live對象需要survivor擁有16690480?/50% =?33,380,960的空間也就是32M。假設原來的配置為:-Xmx1536m -Xms1536m -Xmn512m -XX:SurvivorRatio=30,現在我們采用增加新生代空間不動eden空間的調優方式,那么配置應該變成-Xmx1568m -Xms1568m -Xmn544m -XX:SurvivorRatio=15。注意Xmn變為了544(512+32),SurvivorRatio=15=544/32-2。當然也可以通過不動新生代空間減小eden空間的辦法,但還是盡量使用第一種方法。-XX:TargetSurvivorRatio=<percent>能夠指定target survivor space occupancy,默認值為50%。Java代碼??
  • Desired?survivor?size?8388608?bytes,?new?threshold?1?(max?15)??
  • -?age?1:?16690480?bytes,?16690480?total??
  • 21. 以下現象暗示survivor的空間太小:1.?new tenuring threshold<max?tenuring threshold;2. ?desired survivor size(見上圖)<?total surviving bytes數。從上圖來看,1〈15;8388608<16690480所以需要調優survivor大小。再看下圖,15==15;16777216>7320248所以是一個比較合理的survivor配置。Java代碼??
  • Desired?survivor?size?16777216?bytes,?new?threshold?15?(max?15)??
  • -?age?1:?6115072?bytes,?6115072?total??
  • -?age?2:?286672?bytes,?6401744?total??
  • -?age?3:?115704?bytes,?6517448?total??
  • -?age?4:?95932?bytes,?6613380?total??
  • -?age?5:?89465?bytes,?6702845?total??
  • -?age?6:?88322?bytes,?6791167?total??
  • -?age?7:?88201?bytes,?6879368?total??
  • -?age?8:?88176?bytes,?6967544?total??
  • -?age?9:?88176?bytes,?7055720?total??
  • -?age?10:?88176?bytes,?7143896?total??
  • -?age?11:?88176?bytes,?7232072?total??
  • -?age?12:?88176?bytes,?7320248?total??
  • CMS的調優:22.?CMS garbage collector的調優主要目標是保持老生代有足夠可獲得的空間和后續避免stop-the-world compacting?garbage collections。23.?concurrent mode failure暗示了Stop-the-world compacting garbage collections in CMS,如下圖,如果發生了這種情況需要通過命令-XX:CMSInitiatingOccupancyFraction=65(這里表示老生代空間占用65%)修改CMS?garbage collection cycle啟動時間。另外還有一個相關的命令-XX:+UseCMSInitiatingOccupancyOnly,它保證所有的CMS?garbage collection cycle都按照設定的比例來啟動,如果沒有設置后者,那么僅有第一個CMS?garbage collection cycle是按照設定的比例啟動,之后會根據JVM自適應的方式調整啟動時間。建議一起使用這兩個命令。CMSInitiatingOccupancyFraction值應該大于live data size(一個fullGC后heap的占用量),如果小于這個值,那么CMS collector會運行得過于頻繁。一個經驗值是至少1.5倍live data size。Java代碼??
  • 174.445:?[GC?174.446:?[ParNew:?66408K->66408K(66416K),?0.0000618??
  • secs]174.446:?[CMS?(concurrent?mode?failure):?161928K->162118K(175104K),??
  • 4.0975124?secs]?228336K->162118K(241520K)??
  • 24. 如果觀察到CMS-initial-mark——〉CMS-concurrent-reset過程中heap的占用變化不大(比如說就幾M或幾十M),說明CMS cycle工作的太早,表示需要通過-XX:CMSInitiatingOccupancyFraction and -XX:+UseCMSInitiatingOccupancyOnly來增大老生代空間占用率。296358K-〉292925K變化不大。Java代碼??
  • [ParNew?390868K-><strong><em>296358K</em></strong>(773376K),?0.1882258?secs]??
  • [CMS-initial-mark?298458K(773376K),?0.0847541?secs]??
  • [ParNew?401318K->306863K(773376K),?0.1933159?secs]??
  • [CMS-concurrent-mark:?0.787/0.981?secs]??
  • [CMS-concurrent-preclean:?0.149/0.152?secs]??
  • [CMS-concurrent-abortable-preclean:?0.105/0.183?secs]??
  • [CMS-remark?374049K(773376K),?0.0353394?secs]??
  • [ParNew?407285K->312829K(773376K),?0.1969370?secs]??
  • [ParNew?405554K->311100K(773376K),?0.1922082?secs]??
  • [ParNew?404913K->310361K(773376K),?0.1909849?secs]??
  • [ParNew?406005K->311878K(773376K),?0.2012884?secs]??
  • [CMS-concurrent-sweep:?2.179/2.963?secs]??
  • [CMS-concurrent-reset:?0.010/0.010?secs]??
  • [ParNew?387767K-><strong><em>292925K</em></strong>(773376K),?0.1843175?secs]??
  • 下面這個就比較正常了,546360K-〉350518K變化比較大。Java代碼??
  • [ParNew?640710K-><strong><em>546360K</em></strong>(773376K),?0.1839508?secs]??
  • [CMS-initial-mark?548460K(773376K),?0.0883685?secs]??
  • [ParNew?651320K->556690K(773376K),?0.2052309?secs]??
  • [CMS-concurrent-mark:?0.832/1.038?secs]??
  • [CMS-concurrent-preclean:?0.146/0.151?secs]??
  • [CMS-concurrent-abortable-preclean:?0.181/0.181?secs]??
  • [CMS-remark?623877K(773376K),?0.0328863?secs]??
  • [ParNew?655656K->561336K(773376K),?0.2088224?secs]??
  • [ParNew?648882K->554390K(773376K),?0.2053158?secs]??
  • [ParNew?489586K->395012K(773376K),?0.2050494?secs]??
  • [ParNew?463096K->368901K(773376K),?0.2137257?secs]??
  • [CMS-concurrent-sweep:?4.873/6.745?secs]??
  • [CMS-concurrent-reset:?0.010/0.010?secs]??
  • [ParNew?445124K-><strong><em>350518K</em></strong>(773376K),?0.1800791?secs]??
  • [ParNew?455478K->361141K(773376K),?0.1849950?secs]??
  • 說明CMS cycle工作的太晚的例子(下圖),CMS周期還沒有走完就馬上執行了fullGC。因此要減小XX:CMSInitiatingOccupancyFraction。Java代碼??
  • [ParNew?742993K->648506K(773376K),?0.1688876?secs]??
  • [ParNew?753466K->659042K(773376K),?0.1695921?secs]??
  • [CMS-initial-mark?661142K(773376K),?0.0861029?secs]??
  • [Full?GC?645986K->234335K(655360K),?8.9112629?secs]??
  • [ParNew?339295K->247490K(773376K),?0.0230993?secs]??
  • [ParNew?352450K->259959K(773376K),?0.1933945?secs]??
  • 總之,要得到一個合理的CMSInitiatingOccupancyFraction值需要設置各種嘗試值,然后觀察日志數據,最終方可作出選擇。25. 以下日志內容表明系統進行了顯示的fullGC(System.gc()),RMI應用會在某些時刻執行顯示GC。Java代碼??
  • [Full?GC?(System)??
  • [CMS:?418061K->428608K(16384K),?0.2539726?secs]??
  • 418749K->4288608K(31168K),??
  • [CMS?Perm?:?32428K->32428K(65536K)],??
  • 0.2540393?secs]??
  • [Times:?user=0.12?sys=0.01,?real=0.25?secs]??
  • 26.?-XX:ParallelGCThreads=<n>也能決定CMS中并發rermark線程數。在Java 6 Update 23中,ParallelGCThreads的默認值為:如果Runtime.availableProcessors()地值小于等于8,其值就是處理器的數目,否則,其值為處理數目*5/8。當機器上還運行有其他的應用時,需要將該值調整小于默認值。27.?-XX:+CMSScavengeBeforeRemark可以減少remark的duration值,因為老生代的對象有的會依賴于新生代的對象,當增加了這個命令時會在remark之前執行一次minorGC的操作,從而可以減少老生代到新生代的reachable對象數。28. 如果應用有很多的Reference or finalizable objects,那么可以使用-XX:+ParallelRefProcEnabled來減少duration。并行GC的調優:29. 并行GC的調優主要是讓其避免fullGC。30. 并行GC支持(僅它支持)UseAdaptiveSizePolicy,它會自動地去調整新生代的空間,因此在對并行GC進行調優時需要關閉它-XX:-UseAdaptiveSizePolicy。調優前先要監控日志,使用如下配置:-XX:+PrintGCDateStamps, -XX:PrintGCDetails,-XX:+PrintAdaptiveSizePolicy。31.當發生fullGC,首先確認old generation space是否大于等于1.5倍live data size,如果小就增大。其次查看日志看是否有overflow: true,如果有說明老生代空間不夠大,或者說是survivor的空間太小。Java代碼??
  • [GCAdaptiveSizePolicy::compute_survivor_space_size_and_thresh:??
  • survived:?446113911??
  • promoted:?10904856??
  • overflow:?true??
  • [PSYoungGen:?6493788K->233888K(9437184K)]??
  • 7959281K->2662511K(13631488K),?0.0797732?secs]??
  • [Times:?user=0.59?sys=0.00,?real=0.08?secs]??
  • 32.?調優survivor空間,通過多次觀察找到一個最大的sruvivored值(來自于上面的日志)假設這個值為500M,那么需要的survivor空間大小=500M/50%(TargetSurvivorRatio的默認值為50%)=1G。然后根據這個值來調整head的大小(在內存還可分配的情況下,盡量不要動老生代/eden空間的大小)。當沒有辦法下需要縮小老生代空間時必須保證老生代的空間值為1.5倍于live data size。如果實在內存緊張也可以考慮增大TargetSurvivorRatio值。33. 一條原則:并行GC的開銷不應該大于5%。其他方面:1. 如果應用有大的分配率,但是這些對象的存活期卻很短,需要考慮更大的新生代空間,甚至超過老生代。2. 如果應用的提拔率很低,那么可以考慮讓old generation space<live data size。3. 逃逸分析——Escape Analysis。-XX:+DoEscapeAnalysis4. 偏向鎖——Biased Locking。5. 大內存頁——Large Pages。

    總結

    以上是生活随笔為你收集整理的性能监控/优化系列——JVM监控/调优的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。