国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

jvm性能優(yōu)化

WelliJhon / 2706人閱讀

摘要:前言入門垃圾回收機(jī)制后,接下來可以學(xué)習(xí)性能調(diào)優(yōu)了。輸出老年代空間的性能數(shù)據(jù)。新生代最小空間容量,單位。擁有者表示線程成功競爭到對象鎖。線程狀態(tài),未啟動(dòng)的。,無限期等待另一個(gè)線程執(zhí)行特定操作。主要調(diào)優(yōu)參數(shù)設(shè)定堆內(nèi)存大小,這是最基本的。

Java程序員進(jìn)階三條必經(jīng)之路:數(shù)據(jù)庫、虛擬機(jī)、異步通信。

前言

入門JVM垃圾回收機(jī)制后,接下來可以學(xué)習(xí)性能調(diào)優(yōu)了。主要有兩部分內(nèi)容:

JDK工具的使用。

調(diào)優(yōu)策略。

兵器譜 jps

列出正在運(yùn)行的虛擬機(jī)進(jìn)程,用法如下:

jps [-option] [hostid]

| 選項(xiàng) | 作用 |
| -------- | -----: |
| q | 只輸出LVMID,省略主類的名稱 |
| m | 輸出main method的參數(shù) |
| l | 輸出完全的包名,應(yīng)用主類名,jar的完全路徑名 |
| v | 輸出jvm參數(shù)?|

jstat

監(jiān)視虛擬機(jī)運(yùn)行狀態(tài)信息,使用方式:

jstat -

| 選項(xiàng) | 作用 |
| -------- | -----: |
| gc | 輸出每個(gè)堆區(qū)域的當(dāng)前可用空間以及已用空間,GC執(zhí)行的總次數(shù),GC操作累計(jì)所花費(fèi)的時(shí)間。|
| gccapactiy | 輸出每個(gè)堆區(qū)域的最小空間限制(ms)/最大空間限制(mx),當(dāng)前大小,每個(gè)區(qū)域之上執(zhí)行GC的次數(shù)。(不輸出當(dāng)前已用空間以及GC執(zhí)行時(shí)間)。|
| gccause | 輸出-gcutil提供的信息以及最后一次執(zhí)行GC的發(fā)生原因和當(dāng)前所執(zhí)行的GC的發(fā)生原因。 |
| gcnew | 輸出新生代空間的GC性能數(shù)據(jù)。|
| gcnewcapacity | 輸出新生代空間的大小的統(tǒng)計(jì)數(shù)據(jù)。|
| gcold | 輸出老年代空間的GC性能數(shù)據(jù)。|
| gcoldcapacity | 輸出老年代空間的大小的統(tǒng)計(jì)數(shù)據(jù)。|
| gcpermcapacity | 輸出持久帶空間的大小的統(tǒng)計(jì)數(shù)據(jù)。|
| gcutil | 輸出每個(gè)堆區(qū)域使用占比,以及GC執(zhí)行的總次數(shù)和GC操作所花費(fèi)的事件。|
比如:

jstat -gc 28389 1s

每隔1秒輸出一次JVM運(yùn)行信息:

S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   
52416.0 52416.0 4744.9  0.0   419456.0 28180.6  2621440.0   439372.6  131072.0 33564.8 160472 1760.603  61      2.731 1763.334

| 列 | 說明 | jstat參數(shù) |
| -------- | -----: | -----: |
| S0C | Survivor0空間的大小。單位KB。| -gc -gccapacity -gcnew -gcnewcapacity |
| S1C | Survivor1空間的大小。單位KB。| -gc -gccapacity -gcnew -gcnewcapacity |
| S0U | Survivor0已用空間的大小。單位KB。| -gc -gcnew |
| S1U | Survivor1已用空間的大小。單位KB。| -gc -gcnew |
| EC | Eden空間的大小。單位KB。| -gc -gccapacity -gcnew -gcnewcapacity |
| EU | Eden已用空間的大小。單位KB。| -gc-gcnew |
| OC | 老年代空間的大小。單位KB。| -gc -gccapacity -gcold -gcoldcapacity |
| OU | 老年代已用空間的大小。單位KB。| -gc -gcold |
| PC | 持久代空間的大小。單位KB。| -gc -gccapacity -gcold -gcoldcapacity -gcpermcapacity |
| PU | 持久代已用空間的大小。單位KB。| -gc -gcold |
| YGC | 新生代空間GC時(shí)間發(fā)生的次數(shù)。| -gc -gccapacity -gcnew -gcnewcapacity -gcold -gcoldcapacity -gcpermcapacity -gcutil -gccause |
| YGCT | 新生代GC處理花費(fèi)的時(shí)間。| -gc-gcnew-gcutil-gccause |
| FGC | full GC發(fā)生的次數(shù)。| -gc -gccapacity -gcnew -gcnewcapacity -gcold -gcoldcapacity -gcpermcapacity -gcutil -gccause |
| FGCT | full GC操作花費(fèi)的時(shí)間。| -gc -gcold -gcoldcapacity -gcpermcapacity -gcutil -gccause |
| GCT | GC操作花費(fèi)的總時(shí)間。| -gc -gcold -gcoldcapacity -gcpermcapacity -gcutil -gccause |
| NGCMN | 新生代最小空間容量,單位KB。| -gccapacity -gcnewcapacity |
| NGCMX | 新生代最大空間容量,單位KB。| -gccapacity -gcnewcapacity |
| NGC | 新生代當(dāng)前空間容量,單位KB。| -gccapacity -gcnewcapacity |
| OGCMN | 老年代最小空間容量,單位KB。 | -gccapacity-gcoldcapacity |
| OGCMX | 老年代最大空間容量,單位KB。| -gccapacity-gcoldcapacity |
| OGC | 老年代當(dāng)前空間容量制,單位KB。| -gccapacity -gcoldcapacity |
| PGCMN | 持久代最小空間容量,單位KB。| -gccapacity -gcpermcapacity |
| PGCMX | 持久代最大空間容量,單位KB。| -gccapacity -gcpermcapacity |
| PGC | 持久代當(dāng)前空間容量,單位KB。| -gccapacity -gcpermcapacity |
| PC | 持久代當(dāng)前空間大小,單位KB。| -gccapacity-gcpermcapacity |
| PU | 持久代當(dāng)前已用空間大小,單位KB。| -gc -gcold |
| LGCC | 最后一次GC發(fā)生的原因。| -gccause |
| GCC | 當(dāng)前GC發(fā)生的原因。| -gccause |
| TT | 老年化閾值。被移動(dòng)到老年代之前,在新生代空存活的次數(shù)。| -gcnew |
| MTT | 最大老年化閾值。被移動(dòng)到老年代之前,在新生代空存活的次數(shù)。| -gcnew |
| DSS | 幸存者區(qū)所需空間大小,單位KB。| -gcnew |

jmap

生成堆存儲(chǔ)快照,使用方式:

jmap [ -option ] 

| 選項(xiàng) | 作用 |
| -------- | -----: |
| dump | 生成堆存儲(chǔ)快照,格式為:-dump:[live, ]format=b, file=,live說明是否只dump出存活的對象。 |
| heap | 顯示java堆詳細(xì)信息,如使用那種回收器、參數(shù)配置、分代狀況等。|
| histo | 顯示堆中對象統(tǒng)計(jì)信息,包括類、實(shí)例數(shù)量、合計(jì)容量。|

jstack

生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照,幫助定位線程出現(xiàn)長時(shí)間停頓的原因,用法:

jstack 

Monitor

Monitor是 Java中用以實(shí)現(xiàn)線程之間的互斥與協(xié)作的主要手段,它可以看成是對象或者Class的鎖。每一個(gè)對象都有,也僅有一個(gè) monitor。下面這個(gè)圖,描述了線程和 Monitor之間關(guān)系,以及線程的狀態(tài)轉(zhuǎn)換圖:

進(jìn)入?yún)^(qū)(Entrt Set):表示線程通過synchronized要求獲取對象的鎖,但并未得到。
擁有者(The Owner):表示線程成功競爭到對象鎖。
等待區(qū)(Wait Set):表示線程通過對象的wait方法,釋放對象的鎖,并在等待區(qū)等待被喚醒。

線程狀態(tài)

NEW,未啟動(dòng)的。不會(huì)出現(xiàn)在Dump中。

RUNNABLE,在虛擬機(jī)內(nèi)執(zhí)行的。

BLOCKED,等待獲得監(jiān)視器鎖。

WATING,無限期等待另一個(gè)線程執(zhí)行特定操作。

TIMED_WATING,有時(shí)限的等待另一個(gè)線程的特定操作。

TERMINATED,已退出的。

舉個(gè)例子:

package com.jiuyan.mountain.test;

import java.util.concurrent.TimeUnit;

/**
 * Hello world!
 * 
 */
public class App {

     public static void main(String[] args) throws InterruptedException {
         MyTask task = new MyTask();
         Thread t1 = new Thread(task);
         t1.setName("t1");
         Thread t2 = new Thread(task);
             t2.setName("t2");
             t1.start();
             t2.start();
    }

}

class MyTask implements Runnable {

     private Integer mutex;
      
     public MyTask() {
         mutex = 1;
     }
      
     @Override
     public void run() {
         synchronized (mutex) {
             while(true) {
                 System.out.println(Thread.currentThread().getName());
                 try {
                     TimeUnit.SECONDS.sleep(5);
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
              }
          }
     }
    
}

線程狀態(tài):

"t2" prio=10 tid=0x00007f7b2013a800 nid=0x67fb waiting for monitor entry [0x00007f7b17087000]
 java.lang.Thread.State: BLOCKED (on object monitor)
  at com.jiuyan.mountain.test.MyTask.run(App.java:35)
  - waiting to lock <0x00000007d6b6ddb8> (a java.lang.Integer)
  at java.lang.Thread.run(Thread.java:745)

"t1" prio=10 tid=0x00007f7b20139000 nid=0x67fa waiting on condition [0x00007f7b17188000]
 java.lang.Thread.State: TIMED_WAITING (sleeping)
  at java.lang.Thread.sleep(Native Method)

t1沒有搶到鎖,所以顯示BLOCKED。t2搶到了鎖,但是處于睡眠中,所以顯示TIMED_WAITING,有限等待某個(gè)條件來喚醒。
把睡眠的代碼去掉,線程狀態(tài)變成了:

"t2" prio=10 tid=0x00007fa0a8102800 nid=0x6a15 waiting for monitor entry [0x00007fa09e37a000]
 java.lang.Thread.State: BLOCKED (on object monitor)
  at com.jiuyan.mountain.test.MyTask.run(App.java:35)
  - waiting to lock <0x0000000784206650> (a java.lang.Integer)
  at java.lang.Thread.run(Thread.java:745)

 "t1" prio=10 tid=0x00007fa0a8101000 nid=0x6a14 runnable [0x00007fa09e47b000]
 java.lang.Thread.State: RUNNABLE
  at java.io.FileOutputStream.writeBytes(Native Method)
  

t1顯示RUNNABLE,說明正在運(yùn)行,這里需要額外說明一下,如果這個(gè)線程正在查詢數(shù)據(jù)庫,但是數(shù)據(jù)庫發(fā)生死鎖,雖然線程顯示在運(yùn)行,實(shí)際上并沒有工作,對于IO型的線程別只用線程狀態(tài)來判斷工作是否正常。
把MyTask的代碼小改一下,線程拿到鎖之后執(zhí)行wait,釋放鎖,進(jìn)入等待區(qū)。

public void run() {
     synchronized (mutex) {
         if(mutex == 1) {
             try {
                 mutex.wait();
             } catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
      }
  }

線程狀態(tài)如下:

"t2" prio=10 tid=0x00007fc5a8112800 nid=0x5a58 in Object.wait() [0x00007fc59b58c000]
 java.lang.Thread.State: WAITING (on object monitor)
  at java.lang.Object.wait(Native Method)

"t1" prio=10 tid=0x00007fc5a8111000 nid=0x5a57 in Object.wait() [0x00007fc59b68d000]
 java.lang.Thread.State: WAITING (on object monitor)
  at java.lang.Object.wait(Native Method)

兩個(gè)線程都顯示WAITING,這次是無限期的,需要重新獲得鎖,所以后面跟了on object monitor
再來個(gè)死鎖的例子:

package com.jiuyan.mountain.test;

import java.util.concurrent.TimeUnit;

/**
 * Hello world!
 * 
 */
public class App {

  public static void main(String[] args) throws InterruptedException {
      MyTask task1 = new MyTask(true);
      MyTask task2 = new MyTask(false);
      Thread t1 = new Thread(task1);
      t1.setName("t1");
      Thread t2 = new Thread(task2);
      t2.setName("t2");
      t1.start();
      t2.start();
  }

}

class MyTask implements Runnable {

  private boolean flag;
  
  public MyTask(boolean flag) {
      this.flag = flag;
  }
  
  @Override
  public void run() {
      if(flag) {
          synchronized (Mutex.mutex1) {
              try {
                  TimeUnit.SECONDS.sleep(1);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              synchronized (Mutex.mutex2) {
                  System.out.println("ok");
              }
          }
      } else {
          synchronized (Mutex.mutex2) {
              try {
                  TimeUnit.SECONDS.sleep(1);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              synchronized (Mutex.mutex1) {
                  System.out.println("ok");
              }
          }
      }
  }
  
}

class Mutex {
  public static Integer mutex1 = 1;
  public static Integer mutex2 = 2;
}

線程狀態(tài):

"t2" prio=10 tid=0x00007f5f9c122800 nid=0x3874 waiting for monitor entry [0x00007f5f67efd000]
 java.lang.Thread.State: BLOCKED (on object monitor)
  at com.jiuyan.mountain.test.MyTask.run(App.java:55)
  - waiting to lock <0x00000007d6c45bd8> (a java.lang.Integer)
  - locked <0x00000007d6c45be8> (a java.lang.Integer)
  at java.lang.Thread.run(Thread.java:745)

"t1" prio=10 tid=0x00007f5f9c121000 nid=0x3873 waiting for monitor entry [0x00007f5f67ffe000]
 java.lang.Thread.State: BLOCKED (on object monitor)
  at com.jiuyan.mountain.test.MyTask.run(App.java:43)
  - waiting to lock <0x00000007d6c45be8> (a java.lang.Integer)
  - locked <0x00000007d6c45bd8> (a java.lang.Integer)
  at java.lang.Thread.run(Thread.java:745)

Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x00007f5f780062c8 (object 0x00000007d6c45bd8, a java.lang.Integer),
which is held by "t1"
"t1":
waiting to lock monitor 0x00007f5f78004ed8 (object 0x00000007d6c45be8, a java.lang.Integer),
which is held by "t2"

這個(gè)有點(diǎn)像哲學(xué)家就餐問題,每個(gè)線程都持有對方需要的鎖,那就運(yùn)行不下去了。

調(diào)優(yōu)策略

兩個(gè)基本原則:

將轉(zhuǎn)移到老年代的對象數(shù)量降到最少。

減少Full GC的執(zhí)行時(shí)間。目標(biāo)是Minor GC時(shí)間在100ms以內(nèi),F(xiàn)ull GC時(shí)間在1s以內(nèi)。

主要調(diào)優(yōu)參數(shù):

設(shè)定堆內(nèi)存大小,這是最基本的。

-Xms:啟動(dòng)JVM時(shí)的堆內(nèi)存空間。

-Xmx:堆內(nèi)存最大限制。

設(shè)定新生代大小。
新生代不宜太小,否則會(huì)有大量對象涌入老年代。

-XX:NewRatio:新生代和老年代的占比。

-XX:NewSize:新生代空間。

-XX:SurvivorRatio:伊甸園空間和幸存者空間的占比。

-XX:MaxTenuringThreshold:對象進(jìn)入老年代的年齡閾值。

設(shè)定垃圾回收器
年輕代:-XX:+UseParNewGC。

老年代:-XX:+UseConcMarkSweepGC。
CMS可以將STW時(shí)間降到最低,但是不對內(nèi)存進(jìn)行壓縮,有可能出現(xiàn)“并行模式失敗”。比如老年代空間還有300MB空間,但是一些10MB的對象無法被順序的存儲(chǔ)。這時(shí)候會(huì)觸發(fā)壓縮處理,但是CMS GC模式下的壓縮處理時(shí)間要比Parallel GC長很多。
G1采用”標(biāo)記-整理“算法,解決了內(nèi)存碎片問題,建立了可預(yù)測的停頓時(shí)間類型,能讓使用者指定在一個(gè)長度為M毫秒的時(shí)間段內(nèi),消耗在垃圾收集上的時(shí)間不得超過N毫秒。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/65568.html

相關(guān)文章

  • [譯]GC專家系列5-Java應(yīng)用性能優(yōu)化的原則

    摘要:在本文中我將會(huì)介紹應(yīng)用性能優(yōu)化的一般原則。性能優(yōu)化的流程圖摘取自和合著的性能,描述了應(yīng)用性能優(yōu)化的處理流程。例如,對每臺(tái)服務(wù)器,你面臨著為單個(gè)分配堆內(nèi)存和運(yùn)行個(gè)并為每個(gè)分配堆內(nèi)存的選擇。不過位能使用堆內(nèi)存最大理論值只有。 原文鏈接:http://www.cubrid.org/blog/dev-platform/the-principles-of-java-application-per...

    lufficc 評論0 收藏0
  • Hack on HHVM —— Facebook是如何優(yōu)化PHP的

    摘要:周四正式發(fā)布了編程語言,將靜態(tài)類型以及一些現(xiàn)代的語言特性引入了。這是對優(yōu)化之路上的新里程碑。但是語言層面的優(yōu)化限制太多,對而言還是不夠用。其次是優(yōu)化運(yùn)行的步驟。在這方面進(jìn)行調(diào)整,可以提升運(yùn)行的性能。值得注意的是,給的影響很大。 Facebook周四正式發(fā)布了Hack編程語言,將靜態(tài)類型以及一些現(xiàn)代的語言特性引入了PHP。這是Facebook對PHP優(yōu)化之路上的新里程碑。 showIm...

    lmxdawn 評論0 收藏0
  • Java性能優(yōu)化JVM內(nèi)存模型

    摘要:內(nèi)存模型首先介紹下程序具體執(zhí)行的過程源代碼文件后綴會(huì)被編譯器編譯為字節(jié)碼文件后綴由中的類加載器加載各個(gè)類的字節(jié)碼文件,加載完畢之后,交由執(zhí)行引擎執(zhí)行在整個(gè)程序執(zhí)行過程中,會(huì)用一段空間來存儲(chǔ)程序執(zhí)行期間需要用到的數(shù)據(jù)和相關(guān)信息,這段空間一般被 [TOC] JVM內(nèi)存模型 首先介紹下Java程序具體執(zhí)行的過程: Java源代碼文件(.java后綴)會(huì)被Java編譯器編譯為字節(jié)碼文件(....

    SQC 評論0 收藏0
  • 學(xué)習(xí)JVM必看書籍

    學(xué)習(xí)JVM的相關(guān)資料 《深入理解Java虛擬機(jī)——JVM高級特性與最佳實(shí)踐(第2版)》 showImg(https://segmentfault.com/img/bVbsqF5?w=200&h=200); 基于最新JDK1.7,圍繞內(nèi)存管理、執(zhí)行子系統(tǒng)、程序編譯與優(yōu)化、高效并發(fā)等核心主題對JVM進(jìn)行全面而深入的分析,深刻揭示JVM的工作原理。以實(shí)踐為導(dǎo)向,通過大量與實(shí)際生產(chǎn)環(huán)境相結(jié)合的案例展示了解...

    shaonbean 評論0 收藏0
  • 性能Java代碼的最佳實(shí)踐

    摘要:高性能代碼的最佳實(shí)踐前言在這篇文章中,我們將討論幾個(gè)有助于提升應(yīng)用程序性能的方法。要獲得有關(guān)應(yīng)用程序需求的最好最可靠的方法是對應(yīng)用程序執(zhí)行實(shí)際的負(fù)載測試,并在運(yùn)行時(shí)跟蹤性能指標(biāo)。 showImg(https://segmentfault.com/img/bVbtgk4?w=256&h=254); 高性能Java代碼的最佳實(shí)踐前言 在這篇文章中,我們將討論幾個(gè)有助于提升Java應(yīng)用程序性...

    stackfing 評論0 收藏0
  • 面試官問我JVM調(diào)優(yōu),我忍不住了!

    面試官:今天要不來聊聊JVM調(diào)優(yōu)相關(guān)的吧?面試官:你曾經(jīng)在生產(chǎn)環(huán)境下有過調(diào)優(yōu)JVM的經(jīng)歷嗎?候選者:沒有面試官:...候選者:嗯...是這樣的,我們一般優(yōu)化系統(tǒng)的思路是這樣的候選者:1. 一般來說關(guān)系型數(shù)據(jù)庫是先到瓶頸,首先排查是否為數(shù)據(jù)庫的問題候選者:(這個(gè)過程中就需要評估自己建的索引是否合理、是否需要引入分布式緩存、是否需要分庫分表等等)候選者:2. 然后,我們會(huì)考慮是否需要擴(kuò)容(橫向和縱向都...

    不知名網(wǎng)友 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<