私人MEMO--性能調優 包括JVM常用調優和系統調優

本文是我的私人Memo,僅僅是大綱備忘作用。一段時間後我會整理好。


JVM調優

    主要是內存方向的調優 各個代的大小,GC策略等等。(GC會導致應用線程掛起 嚴重影響性能 降低GC導致的應用暫停時間很有必要)
    JVM內存 = 新生代+老年代+持久代(方法區)
    -Xms :初始JVM內存大小
    -Xmx :最大JVM內存大小 這倆一般一樣 避免運行期間內存變大
    -Xmn :年輕代內存大小 (一般爲Xmx的1/3)
           年輕代包括Eden和兩個Survivor區 默認8:2 80% 10% 10%
    -XX:SurvivorRatio=X 修改Eden和Survior的大小比例
    老年代的大小無法設置,等於JVM內存-年輕代-持久代 如果沒有-Xmn參數 可以通過-XX:NewRatio=X設置年輕代與老年代的比例 默認1:2
    -XX:PermSize=256M:持久代初始內存大小
    -XX:MaxPermSize=512M:最大持久代內存大小
    -Xss:每個線程的堆棧大小
    -XX:MaxTenuringThreshold :設置新生代存活週期
    比如java -Xmx3550m -Xms3550m -Xmn2g -Xss128k   (jstat分析GC狀況)

    避免新生代大小太小導致minor GC頻繁 並且可能導致minor gc 對象直接進入老年代
    避免新生代設置過大導致老年代變小,使得Full GC頻繁 並且minor GC耗時大幅度增加 新生代一般是JVM內存的1/3左右
    避免Survivor過大或者過小
    合理設置新生代存活週期 -XX:MaxTenuringThreshold 默認值15

系統調優
    CPU消耗嚴重的解決辦法
    1、執行線程沒有任何掛起動作,一旦執行導致CPU沒有機會調度其他線程 造成線程餓死。Thread.sleep()釋放CPU使用權(不釋放鎖) 給其他線程執行機會
       這樣導致單次執行性能降低,但是由於降低CPU消耗,反而提高了總體的平均性能。
    2、線程過多導致線程之間切換次數太多,或者鎖競爭激烈。最簡單的解決辦法就是減少線程數的同時增加一個緩衝隊列(因此不是線程數越多吞吐量越高)。
       另外可以進行鎖優化,協程來支撐更高的併發量。
       當前JDK創建一個Thread對象意味着運行了一個原生線程,當這個線程有任何阻塞動作,這個線程就會被掛起,但是依然佔據線程資源。
       阻塞動作完成,OS恢復線程的上下文,調度執行。
    文件IO消耗嚴重的解決辦法
        造成文件IO消耗嚴重主要因爲多個線程寫大量數據到同一文件,導致寫入越來越慢,鎖搶佔激烈。
    1、異步寫文件,將寫文件的動作改爲異步(比如日誌log4j的AsyncAppender)
    2、批量讀寫,頻繁的讀寫操作對IO消耗很嚴重,批量操作可以提高性能。
    3、限流,將文件IO消耗控制在一個可接受範圍。
    4、限制文件大小。
    網絡IO消耗嚴重的解決方法
    1、限流,限制packet發送頻率
    內存消耗嚴重的解決辦法:
    1、釋放不必要的引用。一個很典型的例子是線程複用情況下使用ThreadLocal導致其中存放對象一直不會被GC
    2、使用對象緩存池。一定程度上可以降低JVM堆內存的使用,大幅提升性能。
    3、合理控制緩存池大小,採用合理的緩存失效算法。太多對象在緩存池反而會造成內存嚴重消耗,Full GC增多。
    4、合理使用SoftReference和WeakReference來進行緩存。SoftReference在內存不夠會回收,WeakReference在Full GC回收。
    資源消耗不多,但是程序執行慢的解決辦法
        一般是鎖競爭激烈以及未充分發揮硬件資源
    1、鎖優化 採用下面的方法:
        a、採用併發包中的類。這裏面許多采用了lock-free、nonblocking算法,減少鎖競爭。
        b、Treiber算法 用於實現無阻塞Stack 採用了AtomicReference基於CAS實現。
        c、Michael-Scott非阻塞隊列算法 基於CAS和AtomicReference實現隊列非阻塞操作。比如J.U.C中的ConcurrentLinkedQueue
        d、減少鎖的使用
        e、拆分鎖 獨佔鎖拆爲多把鎖,如ConcurrentHashMap默認拆分爲16把鎖,提高讀寫速度。(當然這會導致CPU消耗增加)
        f、考慮某些特殊鎖的適用場景 比如CopyOnWrite的實現方式,很適合讀多寫少。
    2、未充分使用硬件資源
        a、CPU未充分使用 可以考慮適當增加線程個數(畢竟多核CPU越來越多)
        b、內存未充分使用 適當增加緩存
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章