日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实战jvisualvm

發布時間:2023/12/10 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实战jvisualvm 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上一次【https://www.cnblogs.com/webor2006/p/10629889.html】已經編寫了一個能在堆空間出現內存溢出的代碼,先來回顧一下:

其中咱們給JVM配置了如下參數:

其中還設置了一個當發生內存溢出時來將內存的信息給dump出來,其實就類似于Android中來分析內存也是需要dump內存信息一樣,如下:

其dump出來的文件在這個目錄之下:

其實這個dump出來的文件也叫做“轉儲”文件,那用何工具來分析呢,有很多工具可以分析,這里學習一下之前也介紹的jvisualvm,它是由oracle基于hospot虛擬機力推的一個集大成者的一個功能超級強大的圖形化分析工具,它是集成了很多的命令行的工具使得我們在一個GUI上看到不管是正在運行的JVM進程的種種信息,包括線程的信息、元空間的信息,堆空間的信息等等,還可以分析我們dump出來的轉儲文件,所以咱們先來打開此工具,在命令行中輸入:

接下來咱們來打開轉儲文件:

接下來就詳細來分析一下該轉儲文件:

堆轉儲上的線程:"main" prio=5 tid=1 RUNNABLEat java.lang.OutOfMemoryError.<init>(OutOfMemoryError.java:48)at java.util.Arrays.copyOf(Arrays.java:3210)Local Variable: class java.lang.Object[]at java.util.Arrays.copyOf(Arrays.java:3181)Local Variable: java.lang.Object[]#301at java.util.ArrayList.grow(ArrayList.java:265)at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)at java.util.ArrayList.add(ArrayList.java:462)Local Variable: com.jvm.memory.MyTest1#64646at com.jvm.memory.MyTest1.main(MyTest1.java:11)Local Variable: java.util.ArrayList#7"Finalizer" daemon prio=8 tid=3 WAITINGat java.lang.Object.wait(Native Method)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)Local Variable: java.lang.ref.ReferenceQueue#26at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:212)Local Variable: java.lang.System$2#1"Signal Dispatcher" daemon prio=9 tid=4 RUNNABLE"Reference Handler" daemon prio=10 tid=2 WAITINGat java.lang.Object.wait(Native Method)at java.lang.Object.wait(Object.java:502)at java.lang.ref.Reference.tryHandlePending(Reference.java:191)at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

可以清晰的看到線程的具體異常信息,其中OutOfMemoryError異常如果在真實項目中出現了肯定就是大問題了,對于它其實都比較熟悉了,還是來瞅一下它的官方對它的解釋:

其中該異常的繼承體系如下 :

好,再回到jvisualvm,目前咱們是在這個視圖上看到的信息:

接著來切換到類瞅一下:

好,接下來再來看另外一個視圖:

也就是說需要在類視圖中來選擇要查看的實例數,所以咱們回到類視圖來操作一下:

此時就可以自動跳到實例數這個視圖了,如下:

而在實例數視圖左側看到有個500個實例的提示:

貌似跟我們在類似圖看到個數不一樣啊:

其實不是500個,還有其它木有展開而已,如下:

接著點擊一下其中的實例,在右側可以看到具體的字段信息,如下:

然后還能看到類加載器相關的信息,很顯然我們自己創業的類是由應用類加載器所加載的:

接著還可以看一下它的父加載器,很顯然是由擴展類加載器加載的:

而它的父加載器很顯然就是根類加載器,也就是null嘛:

進一步對咱們之前學習的類加載器相關的知識進行鞏固,好,再看最后一下視圖:

接下來咱們再來改造一下我們的程序:

咱們先來看一下gc()方法的官方解釋:

它最終調用的是System類中的gc(),如下:

咱們再來瞅下它的gc()注釋:

從上面的解釋也就說明了為啥在實際項目中不鼓勵手動去調這個gc()方法,咱們這樣做目的是為了學習研究僅此而已,當手動調用了gc()之后程序內部發生了啥變化呢?這里還是借用jvisualvm來查看下,首先找到咱們運行的進程:

然后雙擊打開它:

也有幾個視圖,咱們一個個來瞅下,先來看下監視:

可見是實時對進程的情況進行監視的,咱們細看一下:

接下來再切一個視圖:

然后再切另外一個視圖:

最后一個視圖是用來分析性能的:

大致了解下既可,這里我們從jvisualvm的分析中可以發現我們的程序在堆中的使用基本是維持在2MB左右的,如下:

那。。如果我們手動將JVM的堆內存由目前的5MB改成1MB呢,看我們程序雖說主動調用了gc()看是否還會有溢出出現,試一下:

其實很容易理解,我們設置的堆內存是在1MB,而實際我們程序堆內存會在2MB左右,當然會溢出啦。

轉載于:https://www.cnblogs.com/webor2006/p/10646305.html

總結

以上是生活随笔為你收集整理的实战jvisualvm的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。