java visualvm分析_使用VisualVM分析性能
對于java虛擬機,像我這樣工作才兩年的會是比較陌生和神秘,但是時候,需要對JVM有一定的認(rèn)識,并且能夠設(shè)置一些參數(shù)。下面是自己學(xué)習(xí)到的內(nèi)容。
這里需要使用一個java自帶的一個工具,VisualVM。使用IDEA下載一個VisualVM。
一、查看程序的JVM內(nèi)存
首先任務(wù)參數(shù)有不要設(shè)置,然后編寫一個程序。
public class JavaHeapTest {
public final static int OUTOFMEMORY = 200000000;
private String oom;
private int length;
StringBuffer tempOOM = new StringBuffer();
public JavaHeapTest(int leng) {
this.length = leng;
int i = 0;
while (i < leng) {
i++;
try {
tempOOM.append("a");
} catch (OutOfMemoryError e) {
e.printStackTrace();
break;
}
}
this.oom = tempOOM.toString();
}
public String getOom() {
return oom;
}
public int getLength() {
return length;
}
public static void main(String[] args) {
JavaHeapTest javaHeapTest = new JavaHeapTest(OUTOFMEMORY);
System.out.println(javaHeapTest.getOom().length());
}
}
然后使用VIsualVM運行程序。
程序運行起來,但是第一次需要設(shè)置VisualVM的位置
程序運行起來后后堆的情況。
上面的圖是沒有設(shè)置任何程序的事情下做的,為什么需要看堆的大小,因為堆存放對象的實例,一般都會需要設(shè)置該值,在沒有做任何設(shè)置的時候,就會看到堆的內(nèi)存可能達到1G的大小。有時候需要模擬線上環(huán)境的上的Java內(nèi)存大小,在IDEA中設(shè)置下一年堆的大小,這里設(shè)置堆的初始化和最大值都一樣,以避免每次垃圾回收完成后JVM重新分配內(nèi)存
設(shè)置之后運行程序,堆的內(nèi)存變?yōu)樵O(shè)置的大小,但是這個時候有可能出現(xiàn)異常,在我的電腦上就出現(xiàn) java.lang.OutOfMemoryError: Java heap space,該異常就是設(shè)置的堆內(nèi)存太小導(dǎo)致,但是一般情況下不會出現(xiàn)該情況,因為上面的程序并不需要特別大的程序,可能是我的筆記本電腦的原因。
上面知道看堆的大小,接下來可以看一下堆中存儲了什么。在程序運行的時候,需要快速點擊堆dump,然后就看到如下
雙擊某個列表之后查看其中的內(nèi)容,而存儲最多的就是程序中設(shè)置的tempOOM參數(shù),此時知道了堆中存儲最大的內(nèi)容是什么,如果是其他程序,某一個字段占用特多的內(nèi)存,可能就是程序出現(xiàn)問題了,那么就需要對那個字段進行優(yōu)化。
二、查看程序的線程情況
接下來運行下面的程序:
public class DeadLock {
public static void main(String[] args) {
Resource r1 = new Resource();
Resource r0 = new Resource();
Thread myTh1 = new LockThread1(r1, r0);
Thread myTh0 = new LockThread0(r1, r0);
myTh1.setName("DeadLock-1 ");
myTh0.setName("DeadLock-0 ");
myTh1.start();
myTh0.start();
}
}
class Resource {
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
class LockThread1 extends Thread {
private Resource r1, r2;
public LockThread1(Resource r1, Resource r2) {
this.r1 = r1;
this.r2 = r2;
}
@Override
public void run() {
int j = 0;
while (true) {
synchronized (r1) {
System.out.println("The first thread got r1's lock " + j);
synchronized (r2) {
System.out.println("The first thread got r2's lock " + j);
}
}
j++;
}
}
}
class LockThread0 extends Thread {
private Resource r1, r2;
public LockThread0(Resource r1, Resource r2) {
this.r1 = r1;
this.r2 = r2;
}
@Override
public void run() {
int j = 0;
while (true) {
synchronized (r2) {
System.out.println("The second thread got r2's lock " + j);
synchronized (r1) {
System.out.println("The second thread got r1's lock" + j);
}
}
j++;
}
}
}
程序運行之后,查看線程標(biāo)簽后直接告警出現(xiàn)了死鎖的線程。
上面的程序可以看到藍色部分為線程正常運行,×××為等待。
三、使用VisualGC來查看年輕代,老年代的堆內(nèi)存的GC情況,如果是頻繁的GC,那么可能就是內(nèi)存不足,就需要增加堆內(nèi)存。
上面的圖大部分的GC都是在Eden區(qū),即對象都是朝生暮死的,并且發(fā)生了GC time收集到0條GC,那么就是該程序一直運行可以(這里程序運行時間很短,在長時間觀察,可以得到更多的信息,如果是將堆內(nèi)存設(shè)置很小的時候,那么就會經(jīng)常發(fā)生GC的情況)
JVM調(diào)優(yōu),需要變設(shè)置參數(shù),邊進行觀察,這樣更容易理解其中緣由,可以上手試一試。
總結(jié)
以上是生活随笔為你收集整理的java visualvm分析_使用VisualVM分析性能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 链表的基本操作 java_详细实现单链表
- 下一篇: 小米8分辨率是2k吗(我的小米云服务)