1.?ParNew表示CMS收集器在新生代采用多線程進行垃圾回收。DefNew表示順序垃圾收集器在新生代采用單線程進行垃圾回收。2.系統做完CMS cycle后,觀察minorGC的日志,如果日志中發現CMS收集前后的heap占用下降不明顯,那要么是已有的對象太少,以至于找到的unreachable對象很少,這樣浪費費CPU;要么是對象從新生代提拔到老生代的速率超過了CMS所能承受的范圍。總之,出現以上情況表示需要進行性能調優。3.?-XX:+CMSClassUnloadingEnabled?-XX:+CMSPermGenSweepingEnabled,PermGen一般存放一些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代碼??
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代碼??
24. 如果觀察到CMS-initial-mark——〉CMS-concurrent-reset過程中heap的占用變化不大(比如說就幾M或幾十M),說明CMS cycle工作的太早,表示需要通過-XX:CMSInitiatingOccupancyFraction and -XX:+UseCMSInitiatingOccupancyOnly來增大老生代空間占用率。296358K-〉292925K變化不大。Java代碼??