国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

JAVA運(yùn)行時(shí)問題診斷-工具應(yīng)用篇

2019-11-14 15:40:29
字體:
供稿:網(wǎng)友

該BLOG內(nèi)容是之前在部門組織討論運(yùn)行時(shí)問題時(shí)自己寫的PPT內(nèi)容,內(nèi)容以點(diǎn)帶面,主要是方便以后自己回顧查看。

大綱包括:1、運(yùn)行時(shí)問題分類 2、服務(wù)器自帶工具 3、其他工具 4、例子 5、實(shí)際情況

運(yùn)行時(shí)問題分類-軟件角度:1、內(nèi)存泄漏,對象未釋放 2、線程阻塞、死鎖 3、線程死循環(huán) 4、網(wǎng)絡(luò)IO連接超時(shí)時(shí)間過長 5、磁盤不可寫 .....

運(yùn)行時(shí)問題分類-硬件角度:1、內(nèi)存占用高 2、CPU占用高 3、網(wǎng)絡(luò)無反應(yīng) 4、硬盤空間滿 ....

linux指令:1、top, top -Hp pid 2、free 3、df 4、netstat, netstat -natp ...

JDK指令:1、jps, jps -v 2、jstack, jstack pid 3、jmap, jmap -dump:format=b,file=/opt/...  4、jstat, jstat -gcutil(gc,gccapacity) pid ....

工具:

實(shí)時(shí)分析工具: 1、Jconsole 2、VisualVM  3、JPRofiler  4、javaMelody  5、LambdaProbe ....

離線分析工具: 1、MemoryAnalyzer tool  2、Thread Dump Analyzer ....

DEMO:1、內(nèi)存溢出  2、CPU占用過高  3、線程死鎖  4、線程阻塞

準(zhǔn)備工作:堆棧內(nèi)存設(shè)置低一點(diǎn),打印GC日志和OOM時(shí)輸出dump文件: set JAVA_OPTS=-server -Xms24m -Xmx50m -XX:PermSize=28M -XX:MaxPermSize=80m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/temp/dump

內(nèi)存溢出:

        Map<String, Person> map = new HashMap<String, Person>();        Object[] array = new Object[1000000];        for (int i = 0; i < 1000000; i++) {            String d = new Date().toString();            Person p = new Person(d, i);            map.put(i + "person", p);            array[i] = p;        }

MAT-關(guān)鍵字(個(gè)人理解,不一定準(zhǔn)確):

Histogram:內(nèi)存中的類對象實(shí)例的對象的個(gè)數(shù)和大小

Dominator Tree:堆對象樹,對象大小和占用百分比

Leak Suspects:MAT分析的內(nèi)存泄漏的可疑點(diǎn)

shallow heap:對象自身占用內(nèi)存大小

retained heap:對象自身和引用的對象占用內(nèi)存大小

Merge Shortest Paths to GC Roots:從GC根節(jié)點(diǎn)到該對象的路徑視圖

with outgoing references:對象持有的外部對象引用

with incomming references:對象被哪些外部對象引用

....

 

CPU占用過高:

		int i = 0;		while (i < 1000000) {			i++;			System.out.println(i);			try {				Thread.sleep(0);			} catch (InterruptedException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		}

  

 

線程死鎖:

		Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");		Thread t2 = new Thread(new SyncThread(obj2, obj1), "t2");		t1.start();		try {			Thread.sleep(3000);		} catch (InterruptedException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		t2.start();		synchronized (obj1) {			System.out.println("主線程 lock on " + obj1.getName());		}

  

	private Person obj1;	private Person obj2;	public SyncThread(Person o1, Person o2) {		this.obj1 = o1;		this.obj2 = o2;	}	public void run() {		String name = Thread.currentThread().getName();		System.out.println(name + " acquiring lock on " + obj1.getName());		synchronized (obj1) {			System.out.println(name + " acquired lock on " + obj1.getName());			work();			System.out.println(name + " acquiring lock on " + obj2.getName());			synchronized (obj2) {				System.out.println(name + " acquired lock on " + obj2.getName());				work();			}			System.out.println(name + " released lock on " + obj2.getName());		}		System.out.println(name + " released lock on " + obj1.getName());		System.out.println(name + " finished execution.");	}	private void work() {		try {			Thread.sleep(10000);		} catch (InterruptedException e) {			e.printStackTrace();		}	}

  

 

線程阻塞:

		WaitThread thread1 = new WaitThread();		thread1.setName("線程1");		NotifyThread thread2 = new NotifyThread();		thread2.setName("線程2");		thread1.start();		try {			Thread.sleep(20000);		} catch (InterruptedException e) {			e.printStackTrace();		}		thread2.start();

  

public class NotifyThread extends Thread {	@Override	public void run() {		synchronized (RequestThreadWait.object) {			System.out.println("線程" + Thread.currentThread().getName() + "占用了鎖");			try {				Thread.sleep(20000);			} catch (InterruptedException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}			RequestThreadWait.object.notify();			System.out.println("線程" + Thread.currentThread().getName() + "調(diào)用了object.notify()");			try {				Thread.sleep(20000);			} catch (InterruptedException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		}		System.out.println("線程" + Thread.currentThread().getName() + "釋放了鎖");	}}public class WaitThread extends Thread {	public void run() {		synchronized (RequestThreadWait.object) {			System.out.println("線程" + Thread.currentThread().getName() + "獲取到了鎖開始");			try {				RequestThreadWait.object.wait();			} catch (InterruptedException e) {			}			System.out.println("線程" + Thread.currentThread().getName() + "獲取到了鎖結(jié)束!");		}	}}

  

線程狀態(tài)(個(gè)人理解,不一定準(zhǔn)確):

WAITING (parking):線程自身掛起等待,正常

WAITING (on object monitor):線程主動(dòng)執(zhí)行wait,等待資源,如果是自己的程序,需要關(guān)注

BLOCKED (on object monitor):線程阻塞,等待對方釋放資源,如果是互相等待對方阻塞的線程,則發(fā)生死鎖

TIMED_WAITING (on object monitor):線程調(diào)用了wait(long timeout),在特定時(shí)間內(nèi)等待

TIMED_WAITING (sleeping):調(diào)用了sleeping,休眠一段時(shí)間

 

JavaMelody:

LambdaProbe

 

實(shí)際情況:

用戶反饋各種千奇百怪的問題!

網(wǎng)絡(luò)訪問連接不上

網(wǎng)站、接口訪問超時(shí)

特定功能很慢

部分功能部分人打不開

.......

->

ping,telnet,traceroute....

top,top -Hp pid,jstack pid....

jstat -gc,gcutil,gccapacity pid...

jmap -dump:format=b,file=/opt/.... tail, df -lh....

netstat -natp....

.....

生產(chǎn)問題沒有統(tǒng)一解決辦法,具體問題具體分析

內(nèi)存查看:jstat

線程情況查看:top -Hp pid

CPU查看:jstack

網(wǎng)絡(luò)查看:netstat

 

實(shí)際問題分析:

線上查看 服務(wù)器情況分析 獲取內(nèi)存dump 獲取javacore

線下分析 工具調(diào)試分析內(nèi)存線程

代碼調(diào)試 Eclipse Class Decompiler(自動(dòng)反編譯,選擇JD-Core,精確行數(shù))

...

轉(zhuǎn)載請注明:http://lawson.VEVb.com

上面是實(shí)際生產(chǎn)問題的自己寫的PPT,copy下來的,JDK自帶的工具和指令比較強(qiáng)大,本篇文章沒有太多介紹。

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 汉阴县| 淳化县| 大石桥市| 祥云县| 松原市| 南通市| 吉安市| 衡水市| 舞阳县| 确山县| 南投县| 库伦旗| 西昌市| 米脂县| 福贡县| 抚远县| 松江区| 昌平区| 哈密市| 通海县| 山东| 阿拉善盟| 永吉县| 营山县| 大丰市| 乌苏市| 高密市| 乐亭县| 高安市| 泸定县| 福安市| 措勤县| 北京市| 诸暨市| 荥经县| 南阳市| 康平县| 马公市| 台南县| 锦屏县| 海阳市|