JVM調(diào)優(yōu)1- JVM參數(shù)及JDK自帶的JVM查詢工具

1. JVM的運行參數(shù)

1.1 三種參數(shù)類型
  • 標(biāo)準(zhǔn)參數(shù)

    • help
    • -version
  • -X參數(shù) (非標(biāo)準(zhǔn)參數(shù))

    • -Xint
    • -Xcomp
  • -XX參數(shù)(使用率比較高, 常用語jvm調(diào)優(yōu))

    • -XX:newSize
    • -XX:+UseSeriaIGC
1.2 標(biāo)準(zhǔn)參數(shù)

-D 設(shè)置系統(tǒng)屬性: java -Dstr=hello

String str = System.getProperty("str")
println(str)

輸出結(jié)果: hello
JVM的兩個啟動模式: server和client
JVM在啟動的時候回根據(jù)硬件和操作系統(tǒng)自動選擇是使用Server還是Client類型的JVM
64位操作系統(tǒng)只有Server類型翠胰,沒有Client

1.3 非標(biāo)準(zhǔn)參數(shù)

JVM的運行模式:
-Xint: 解釋模式誉裆, 強制要求JVM執(zhí)行所有的字節(jié)碼(interpreted mode)
-Xcomp: 編譯模式渴语,JVM在第一次使用時會把所有字節(jié)碼編譯成本地代碼(compiled mode)
-Xmixed:混合模式衙传,將解釋模式和編譯模式混合使用, JVM默認的模式憨奸, 也是推薦的模式(mixed mode)

1.4 -XX 參數(shù)

-XX參數(shù)也是非標(biāo)準(zhǔn)參數(shù)驱富, 主要用于JVM的調(diào)優(yōu)和debug操作
兩種使用方式:

  • boolean類型
    格式: -XX:[+-]<name> 表示啟用或者禁用name指令
    -XX:+DisableExplicitGC表示禁用手動調(diào)用gc操作锚赤, System.gc()無效
  • 非boolean類型
    格式: -XX<name>=<value> 表示name的屬性值為value
    -XX:NewRatie=1 表示新生代和老年代的比值
1.5 -Xms, -Xmx

-Xms和-Xmx分別是設(shè)置jvm的堆內(nèi)存的初始大小和最大大小
-Xms512m相當(dāng)于: -XX:InitialHeapSize=512m
-Xms2048m相當(dāng)于:-XX:MaxHeapSize=2048m

JVM啟動時會自動設(shè)置Heap size的值, -Xms初始空間是物理內(nèi)存的1/64, -Xmx最大值時物理空間的1/4褐鸥。
進行JVM優(yōu)化時线脚, 可將-Xms和-Xmx設(shè)置值相同, 最大值不超過物理內(nèi)存的80%

1.6 查看jvm運行參數(shù):

運行java命令時打印參數(shù): -XX:+PrintFlagsFinal
參數(shù)列表中: = 表示默認值, :=表示值被修改過

1.7 查看正在運行的進程的jvm信息

jps -l查看當(dāng)前系統(tǒng)中所有運行的java項目的進程id及詳細包信息
jinfo -flags 29200 查看進程id為29200進程的所有jvm參數(shù)信息
jinfo -flag MaxheapSize 29200 查看pid下的具體某一jvm信息

image.png

2. jvm的內(nèi)存模型

jvm的內(nèi)存模型1.7和1.8有較大的區(qū)別

2.1 jdk1.7的堆內(nèi)存模型:
  • 年輕區(qū): 新new的一些對象會在這個區(qū)域浑侥,young區(qū)被分為:Eden區(qū)和兩個大小嚴(yán)格相同的Survivor區(qū)姊舵, 當(dāng)Eden區(qū)變滿時, 數(shù)據(jù)會移到Survior中寓落,幾次jvm垃圾收集后括丁, 依然存活的Survivor會知道老年區(qū)
  • 老年區(qū):tenured區(qū)主要保存生命周期長的對象, 一般是一些老的對象
  • 永久區(qū): 主要保存class, method, field對象伶选, 這部分空間一般不會溢出
2.2 jdk1.8的堆內(nèi)存模型

年輕區(qū):Eden+2*Survivor
老年區(qū):OldGen
元數(shù)據(jù)空間(Metaspace):Matespace是不是在虛擬機內(nèi)部史飞, 而是占用服務(wù)器的內(nèi)存空間,這是和1.7最大的區(qū)別

2.3 為什么廢除了1.7的永久區(qū)

現(xiàn)實中是因為永久代內(nèi)存總會發(fā)生不夠用或者內(nèi)存泄漏仰税, 基于此將永久區(qū)廢棄祸憋, 改為使用本地的內(nèi)存空間

2.4 通過jstat命令進行查看堆內(nèi)存的使用情況

jstat 參數(shù)指令 進程id 時間間隔 查詢次數(shù)
jstat -class 29200 查看類加載情況
loaded: 加載類的數(shù)量
Bytes:類占得空間
uloaded:未加載類的數(shù)量
Time: 加載占用的時間

image.png

jstat -compiler 29200 查看編譯情況

image.png

查看垃圾回收器的使用情況
jstat -gc 29200 1000 10 每1000毫秒(1秒)鐘打印一次gc使用情況, 總共打印10次

image.png

3. jmap的使用以及內(nèi)存溢出分析

3.1 查看內(nèi)存使用情況

jmap -heap 29200

3.2 查看內(nèi)存中對象數(shù)量及大行の浴:

jmap -histo <pid> | more 查看所有對象的
jmap -histo:live <pid> | more 查看活躍對象的

image.png

[B-> byte
[I -> int
[C->char

3.3 將內(nèi)存使用情況dump到文件中, jhat對快照文件分析

jmap -dump:format=b,file=filename <pid>
例如 jmap -dump:format=b,file=dumptest.dat 29200 會生成一份29200內(nèi)存使用情況的二進制文件dumptest.dat
使用jhat對dump的二進制文件分析:jhat port 9999 dumptest.dat

image.png

瀏覽器訪問7000端口:
image.png

4. 內(nèi)存溢出的定位與分析

內(nèi)存溢出在生產(chǎn)環(huán)境中經(jīng)常會遇到, 比如不斷地將數(shù)據(jù)寫入到一個集合中掸鹅,出現(xiàn)了死循環(huán)塞帐, 讀取超大文件等等,都可能造成內(nèi)存溢出巍沙。

4.1模擬內(nèi)存溢出:

設(shè)置jvm參數(shù): -Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
jvm初始內(nèi)存8m葵姥, 最大內(nèi)存8m, 內(nèi)存溢出時dump內(nèi)存快照
編寫代碼:

    public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<>();
        for (int i = 0; i <= 1000000000; i++){
            String id = "";
            for (int j = 0; j < 1000; j++){
                id += UUID.randomUUID().toString();
            }
            strings.add(id);
        }
    }

mat工具分析內(nèi)存


image.png
4.2 jstack的使用:

有時候我們需要查看jvm中的線程執(zhí)行情況句携, 比如發(fā)現(xiàn)CPU的負載突然增高榔幸,出現(xiàn)了死鎖,死循環(huán)等矮嫉, 由于程序正常運行的削咆,沒有任何的輸出, 從日志方面也看不出什么問題蠢笋, 需要從jvm的內(nèi)部線程的執(zhí)行情況查找并且分析原因拨齐。
jstack <pid> 可以看到當(dāng)前pid進程中所有線程的執(zhí)行情況。

5. jstack中Java中線程的狀態(tài)

  1. 初始狀態(tài)(NEW): 創(chuàng)建一個thread對象昨寞, 但還未調(diào)用start啟動線程瞻惋, 則處于初始狀態(tài)
  2. 運行狀態(tài)(RUNNABLE):
    • 就緒狀態(tài): 等待CPU分配執(zhí)行權(quán), 放在就緒隊列中
    • 運行狀態(tài):獲得CPU的執(zhí)行權(quán)援岩, 一個CPU在同一時間只能執(zhí)行一個線程歼狼,所以每個CPU在每個時刻都只有一條運行態(tài)的線程。
  3. 阻塞狀態(tài)(BLOCKED):java中指請求某一鎖失敗時享怀, 線程會進入阻塞態(tài)羽峰, 阻塞態(tài)會不斷地請求資源, 一旦請求成功就會進入就緒隊列, 等待CPU分配限寞。
  4. 等待狀態(tài)(WAITING):無線等待忍啸, 當(dāng)線程中調(diào)用 wait, join, park等函數(shù)時,線程進入等待狀態(tài)履植,等待線程會釋放CPU以及鎖資源计雌,進入等待隊列, 需要其他線程指示才能繼續(xù)運行玫霎。
  5. 超時等待態(tài) (TIMED_WAITING): 有限等待凿滤,與等待態(tài)的區(qū)別是, 到了超時時間會進入阻塞隊列庶近, 開始競爭鎖翁脆。
  6. 終止態(tài)
5.1死鎖問題

模擬死鎖問題:

   private static Object obj1 = new Object();

    private static Object obj2 = new Object();


    public static void main(String[] args) {
        new Thread(new Thread1()).start();
        new Thread(new Thread2()).start();
    }

    private static class Thread1 implements Runnable{
        @Override
        public void run() {
            synchronized (obj1){
                System.out.println("Thread1 拿到了 obj1 的鎖!");

                try {
                    // 停頓2秒的意義在于鼻种,讓Thread2線程拿到obj2的鎖
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj2){
                    System.out.println("Thread1 拿到了 obj2 的鎖反番!");
                }
            }
        }
    }

    private static class Thread2 implements Runnable{
        @Override
        public void run() {
            synchronized (obj2){
                System.out.println("Thread2 拿到了 obj2 的鎖!");

                try {
                    // 停頓2秒的意義在于叉钥,讓Thread1線程拿到obj1的鎖
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj1){
                    System.out.println("Thread2 拿到了 obj1 的鎖罢缸!");
                }
            }
        }
    }

線程1和線程2相互持續(xù)持有對方需要的鎖資源, 造成死鎖問題投队。
使用jstack查看死鎖進程:


image.png

image.png

jstack查找除了發(fā)生死鎖進程的原因枫疆, 以及對應(yīng)的堆棧信息。

6. 使用JDK子代的 Java VisualVm

綜合的結(jié)合了以上介紹jvm性能查看的jdk自帶可視化工具:

位置: 當(dāng)前jdk安裝目錄bin下的jvisualvm
image.png

既可以查看本地java進程敷鸦, 也可以查看遠程進程

配置遠程java進程如tomcat的啟動文件catalina.sh息楔, 允許jmx遠程監(jiān)控

JAVA_OPTS="
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9999 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false"

開放9999端口, 不需要認證扒披,關(guān)閉ssl認證

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末值依,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谎碍,更是在濱河造成了極大的恐慌鳞滨,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蟆淀,死亡現(xiàn)場離奇詭異拯啦,居然都是意外死亡,警方通過查閱死者的電腦和手機熔任,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門褒链,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疑苔,你說我怎么就攤上這事甫匹。” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵兵迅,是天一觀的道長抢韭。 經(jīng)常有香客問我,道長恍箭,這世上最難降的妖魔是什么刻恭? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮扯夭,結(jié)果婚禮上鳍贾,老公的妹妹穿的比我還像新娘。我一直安慰自己交洗,他們只是感情好骑科,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著构拳,像睡著了一般咆爽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上置森,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天伍掀,我揣著相機與錄音,去河邊找鬼暇藏。 笑死,一個胖子當(dāng)著我的面吹牛濒蒋,可吹牛的內(nèi)容都是我干的盐碱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼沪伙,長吁一口氣:“原來是場噩夢啊……” “哼瓮顽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起围橡,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤暖混,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后翁授,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拣播,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年收擦,在試婚紗的時候發(fā)現(xiàn)自己被綠了贮配。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡塞赂,死狀恐怖泪勒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤圆存,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布叼旋,位于F島的核電站,受9級特大地震影響沦辙,放射性物質(zhì)發(fā)生泄漏夫植。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一怕轿、第九天 我趴在偏房一處隱蔽的房頂上張望偷崩。 院中可真熱鬧,春花似錦撞羽、人聲如沸阐斜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谒出。三九已至,卻和暖如春邻奠,著一層夾襖步出監(jiān)牢的瞬間笤喳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工碌宴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杀狡,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓贰镣,卻偏偏與公主長得像呜象,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子碑隆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容