系統性能優化

1. ClassNotFoundException/NoClassDefFoundError/NoSuchMethodExceptionhtml

       參考關於類加載的博文便可,主要關注類加載的方式,類的版本等信息java

       https://www.cnblogs.com/baihuitestsoftware/articles/6382733.htmllinux

       http://www.javashuo.com/article/p-ohrppvxl-ek.htmlide

2.Cpu us消耗高工具

linux下獲取佔用CPU資源最多的10個進程,能夠使用以下命令組合: 或者top進入後大寫的M性能

//加標題去標題,第三列倒序排序
ps -aux | head -1 ; ps aux | grep -v PID | sort -rn -k +3 | head
//排序
ps -aux | sort -nr -k3 | head -10

       是不是gc過於頻繁,打開gc日誌-Xloggc:./gc.log或者經過jstat -gcutil來查看gc和內存的狀況,這種根據內存問題來處理ui

       下面根據top -H -p/ jstack等命令查看是否有死鎖,很深的循環或遞歸,也多是序列化反序列化之類對象忽然變大,計算忽然增長   spa

/**
 * Created by itworker365 on 5/17/2017.
 */
public class CpuBusyTest implements Runnable{
    public static void main (String[] args) {
        for (int a = 0; a < 1000; a++) {
            CpuBusyTest test = new CpuBusyTest();
            Thread t = new Thread(test, "t-" + a);
            t.start();
        }
    }

    @Override
    public void run() {
        long start = System.currentTimeMillis();
        long k = 0;
        for (long i = 0; i < 2000000000; i++) {
            k = 1 + i;
        }
        System.out.println(Thread.currentThread().getName() + "-----" + (System.currentTimeMillis() - start));
    }

默認TOP按照進程顯示,直接輸入TOP看到佔用最多的進程,以下,%CPU 99.8操作系統

top -H -p ID查看該進程下的線程狀況,若是有一個特別高,能夠找到PID,而後轉換爲16進制,好比2687-》0xA7F,打印進程堆棧 jstack ID在其中找到0xA7F線程

個人例子並無對應,由於中間停掉了,因此意思明白就好,這裏打印出jstack信息,找到對應的線程,查看他的狀態。

 

一個出現死鎖的例子

/**
 * Created by itworker365 on 5/4/2017.
 */
public class LockTest {
    private static String A = "A";
    private static String B = "B";
    public static void main (String[] args) {
        new LockTest().deadlock();
    }
    private void deadlock () {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (A) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (B) {
                        System.out.println("AB");
                    }
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (B) {
                    synchronized (A) {
                        System.out.println("BA");
                    }
                }
            }
        });
        t1.start();
        t2.start();
    }
}

jstack以後顯示deadlock信息

 3. 內存問題

linux下獲取佔用內存資源最多的10個進程,能夠使用以下命令組合:或者top進入後大寫的P

ps -aux | head -1 ; ps aux | grep -v PID | sort -rn -k +4 | head
ps -aux | sort -nr -k4 | head -10

    java.lang.OutOfMemoryError: Unable to create new native thread

    用命令統計出當前總java線程數ps -eLf | grep java -c, 查出當前容許的最大句柄數ulimit -u,對比看是否正確,根據須要作出對應的調整,btrace找到哪裏建立的線程@OnMethod(clazz="java.lang.Thread", method="start")

    Executors.newCachedThreadPool這種來建立了一個沒限制大小的線程池

    java.lang.OutOfMemoryError: Heap Size或GC overhead limit exceeded

    啓動時加入-XX:+HeapDumpOnOutOfMemoryError在溢出時dump內存,以後再經過mat等工具再分析,經過btrace來定位代碼

    PermGen Space 跟蹤class裝載狀況,用traceClassLoading或者btrace,@OnMethod(clazz="java.lang.ClassLoader", method="defineClass")

    native OOM:Direct ByteBuffer(NIO)-XX:MaxDirectMemorySize=500m來實現當Direct ByteBuffer使用到500m後主動觸發fgc來回收

    到底什麼算頻繁,若是每隔10s或更短期就來一次cms gc或full gc纔算得上

    jmap -dump:format=b,file=***log         jhat ***.log或其餘工具分析

    jmap -histo打印加載的對象    jmap -histo:live來觸發fgc

java.lang.OutOfMemoryError: Java heap space堆溢出,大對象屢次沒被回收,對比回收先後的內存使用量

StackOverflowError:遞歸,循環,局部變量過長,參數過多,局部變量做用域外沒有釋放等

java.lang.OutOfMemoryError: unable to create new native thread  操做系統沒有足夠的資源來建立線程,解決方法就是減小線程數量或者-Xss減少單個線程的大小

java.lang.OutOfMemoryError: PermGen space 類太多,是多個classloader或者太多反射動態加載類致使

4. Java進程crash或退出

默認狀況下jdk會生成hs_err[pid].log的文件,core dump打開的話也會生成core dump文件

-XX:+PrintGCDetails

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/log/gcdump

遇到問題分而治之,隔離問題。將問題隔離到儘量小的領域中,好比某個特定系統、特定版本、 甚至特定機器中。以後若是是java的問題,還能夠繼續分析是java應用、容器、或者jdk的問題,最後應該能肯定到某個模塊的某些代碼、一次 commit、一行配置的問題。整個排查問題的過程就是一個從上到下,一步步縮小問題範圍的過程。

狀態數據大體能夠分爲兩類:

一是監控類數據,收集這類數據對於應用的性能影響很小,基本能夠忽略不計,因此能夠持續收集,好比GC log,應用log等;

第二類是某些瞬時數據,這些數據要麼收集的代價很大,很影響系統性能,要麼時效性很高,過了故障點一切可能就都不同了,因此不能 持續收集,必須迅速的在故障出現點自動採集,好比Heap dump,core dump等。

相關文章
相關標籤/搜索