idea中設置JVM參數,簡單理解JVM常見參數,JVM調優

2020-11-04 拉溝IT

idea中設置JVM參數,簡單理解JVM常見參數,JVM調優簡單入門

前面學習了JVM的內存分布,今天就來驗證下。順便通過測試學習一下JVM的幾個參數,不過測試是在idea中,所以先要在idea上設置JVM參數。

一、idea設置全局的JVM參數

一共三步,第一步在菜單欄Help下選擇Edit Customer VM Options.......

第二步:可以看到選中後的參數,然後就可以設置常規參數,設置完成後記得重啟idea。如下圖:

第三步:重啟後,查看結果,在idea的最右下角會顯示總的和使用的,如果沒有顯示可以設置顯示,如下圖,在setting中勾選紅色框那個選項,點擊應用完成。

二、針對應用配置JVM參數

第一步:選擇Run下面的Edit Configurations....

第二步:選擇想配置的應用,然後在右側的VM options設置JVM參數。

三、JVM內存驗證

又要祭出那張內存分布圖了,

如上圖,程序計數器不會拋出異常,先不管了,主要是剩下幾個的驗證。

1、Java堆驗證

從之前的學習知道,堆裡面放的都是對象和數組,主要是對象。首先是控制堆大小的兩個參數-Xms(初始堆大小)、-Xmx(最大對大小)。

測試應用的JVM參數設置:

-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

其中+HeapDumpOnOutOfMemoryError參數可以是內存溢出存儲內存快照,可用於分析錯誤。測試結果如下圖:

紅框內就是創建的文件就是內存快照文件,在你的項目的工作目錄下,這個是內存溢出前存儲的內存情況,可以用專門的工具去分析。這裡分享一個在線的分析網站,把Dump文件傳上去就可以簡單分析下了,網址就不打了,具體如下圖:

2、虛擬機棧和本地方法棧驗證

HotSpot虛擬機不區分虛擬機棧和本地方法棧(通過java -version可查看是什麼虛擬機),所以一起測試了。對應的JVM參數-Xss(每個線程的棧大小)

我們知道棧裡面存的是棧幀,棧幀對應的就是線程的方法,所以只要調用的方法多就可以測試出來,最好的辦法就是遞歸了。

測試應用的參數配置:

-Xss128k -XX:+HeapDumpOnOutOfMemoryError

測試結果如下圖:

虛擬機棧之前說過有兩種溢出,線程請求的棧深度大於虛擬機允許的深度,將拋出StackOverflowError異常。如果虛擬機棧可以動態擴展,當擴展的時候沒有申請到內存的時候拋出OutOfMemoryError。

這裡我們是第一種情況。對於第二種情況,如果在單線程的情況下棧去動態擴展導致內存不足,那麼應該也是屬於棧不能申請到更多空間,所以是棧溢出,可以明顯看出來OutOfMemoryError和StackOverflowError存在包含關係。如果在多個線程下。每個線程的棧都在擴展內存,就會耗光物理內存而造成了OutOfMemoryError。

一個機器的內存是有限的。建立過多線程導致的內存溢出。如果不能減少線程,那麼可以通過減少堆和減少棧容量來換取更多線程。這部分可以深入討論,主要討論各個模塊的關係,和各自的限制。

3、方法區驗證

方法區中主要存儲被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼。所以我們平時遇到的這類異常一般都是加載的類太多,比如spring這類的框架都會對類進行增強,都會使用到CGLib這類字節碼技術,增強的類越多,就需要越大的方法區來保證動態生態的Class可以加載入內存。

jdk8的方法區變成了元空間,使用的是直接內存。所以和jdk7使用的參數不一樣具體參數如下:

jdk7:-XX:PermSize=10m -XX:MaxPermSize=10m

jdk8:-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m

結果如下圖:

jdk8的異常更加明顯,明確表明是了元空間內存溢出。

4、直接內存驗證

直接內存如果不設置和-Xmx(堆最大)一樣。可通過參數-XX:MaxDirectMemorySize來設置直接內存。直接內存一般和NIO有關,DirectByteBuffer中通過Unsafe去操作的直接內存,DirectByteBuffer是通過計算知道內存不足拋出的異常,unsafe.allocateMemory()才是去申請內存的方法。測試代碼如下圖:

測試參數:-Xms20m -XX:MaxDirectMemorySize=10m

直接內存的溢出比較簡單,dump文件也比較小。如果發現內存溢出也沒有明顯異常,dump文件比較小,那麼就應該想到可以能直接內存溢出,是不是程序中使用了NIO的原因。

四、總結

學習了幾個常用JVM參數,總結如下

OutOfMemoryError簡稱OOM,學習了幾個基本的內存溢出後,對以後才能有更好的幫助。工作中遇到了內存溢出時,能根據異常信息來判斷是那個區域的內存溢出,也知道什麼樣的代碼可能會造成這些區域會出現內存溢出,並且知道一些處理手段。

相關焦點

  • 常見的jvm調優策略
    一般來說,jvm的調優策略是沒有一種固定的方法,只有依靠我們的知識和經驗來對項目中出現的問題進行分析,正如吉德林法則那樣當你已經把問題清楚寫出來,就已經解決了一半。雖然JVM調優中沒有固定的策略,但是本文會介紹幾種比較常見的調優策略。
  • JAVA HEAP SPACE解決方法和JVM參數設置
    如果是開發測試,也可以再eclipse中直接設置。Eclipse ->run -arguments 中的VM arguments 中輸入-Xms32m -Xmx800m這個參數就可以了。 再看jmap的dump選項,這個選項是將jvm的堆中內存信息輸出到一個文件中,在我本機執行jmap -dump:file=c:\dump.txt 340 注意340是我本機的java進程pid,dump出來的文件比較 大有10幾M,而且我只是開了tomcat,跑了一個很簡單的應用,且沒有任何訪問,可以想像,大型繁忙的伺服器上,dump出來的文件該有多大。
  • 「Java面試題第一期」有沒有jvm調優經驗?調優方案有哪些?
    調優時機:a. heap 內存(老年代)持續上漲達到設置的最大內存值;b. Full GC 次數頻繁;c. GC 停頓時間過長(超過1秒);d. 應用出現OutOfMemory 等內存異常;e. 應用中有使用本地緩存且佔用大量內存空間;f. 系統吞吐量與響應性能不高或下降。2.
  • 大廠面試系列(一)::JVM基礎
    CMS和G1各自使用的算法以及優缺點內存分配策略(如何在Eden和老年代中分配)、回收策略(Minor GC、Full GC)談談你對上面GC中回收對象中提出的對象有什麼理解?回收那些對象,需要怎麼分辨?你了解的垃圾收集算法有哪些?你了解那些垃圾收集器?線上發送頻繁fullgc如何處理?
  • Java性能調優:JVM性能監控常用方法
    生產環境中監控JVM性能,分析監控數據,可以知道何時需要JVM調優,可見監控是非常重要的。JVM的監控範圍包括垃圾收集、JIT編譯以及類加載。那其中具體都包含哪些?如何監控呢?-h | -v: 顯示幫助或者版本信息】** -c:** 命令行列顯示程序名以及參數-d: 啟動時設置刷新時間間隔-H: 設置線程模式-i: 只顯示活躍進程-n: 顯示指定數量的進程-p:
  • Java面試總結之JVM
    程序計數器(和系統相關) 本地方法棧通常在面試中會圍繞這5個空間展開三、GC算法及垃圾回收器常見的垃圾回收算法:標記-清除,複製,標記-壓縮,分代收集常用的垃圾回收集器:Serial收集器,ParNew收集器,Paralle收集器,Paralle Old收集器,Cms收集器,G1收集器在實際應用中,我們可以根據不同的應用需求及伺服器的配置來配置相應的垃圾回收器
  • Java Jvm 的分配參數概述
    應用程式在運行時,首先會被分配-Xms指定的內存大小,並儘可能的在這個空間段內存中運行程序,當這個值無法滿足應用程式時,jvm才會向作業系統中申請更多的內存,直到內存值達到-Xmx指定的大小,若超過-Xmx指定的大小時,則拋出 OutOfMemoryError異常如果 -Xms的數值較小,那麼JVM為了保證系統儘可能的在指定內存範圍中運行
  • 阿里P8專家用5個小時讓你精通JVM調優,共計3.7G
    前言做java開發的幾乎都知道jvm這個名詞,但是由於jvm對實際的簡單開發的來說關聯的還是不多,一般工作個一兩年(當然不包括愛學習的及專門做性能優化的什麼的),很少有人能很好地去學習及理解什麼是jvm,以及弄清楚jvm的工作原理,個人認為這塊還是非常有必要去認真了解及學習的,特別是剛入門或入門不久的java開發來說,這是java
  • 阿里P8專家用5個小時讓你精通JVM調優,共計3.7G
    前言做java開發的幾乎都知道jvm這個名詞,但是由於jvm對實際的簡單開發的來說關聯的還是不多,一般工作個一兩年(當然不包括愛學習的及專門做性能優化的什麼的),很少有人能很好地去學習及理解什麼是jvm,以及弄清楚jvm
  • 程式設計師:深入理解JVM,從JVM層面來講Java多態
    對多態理解不夠深入的,多半都會答錯;如果能記住口訣:「變量多態看左邊,方法多態看右邊,靜態多態看左邊」的話,肯定就知道答案,但是JVM是如何確定具體調用哪個方法的,有小夥伴思考過嗎?代碼中刻意定義了兩個靜態類型相同但實際類型不同的變量,但編譯器在重載時是通過參數的靜態類型而不是實際類型作為判定依據的。並且靜態類型是編譯器可知的,因此在編譯階段,Javac編譯器會根據參數的靜態類型決定使用哪個重載版本,所以選擇了sayHello(Human)作為調用目標,並把這個方法的符號引用寫到main()方法裡的兩條invokevirtual指令的參數中。
  • jvm參數 -Xms -Xmx -Xmn -Xss調優,及具體實戰垃圾回收機制的配置
    在日常的Java開發中,常見以下問題:內存洩露某個進程突然cpu飆升線程死鎖響應變慢如果遇到了以上這種問題,如何JAVA內存管理、垃圾回收、內存調優,來解決運行日誌、異常堆棧、GC日誌、線程快照、堆快照等問題?
  • JVM性能調優
    1、了解jvm啟動流程:2、了解硬體、系統、進程三個層面的內存之間的概要內存分配,一張圖你就懂堆內存分配,想了解參數的可以到最下面看下備註和建議:先來個日誌(看不懂那就看圖):
  • JVM層面的切面實現 : jvm-sandbox 之 <應用啟動>
    該類存在一個main方法,接收3個參數,並實例化一個CoreLauncher實例,它在構造方法中完成agent的attach動作.注意,SandboxClassLoader位於sandbox-agent.jar包中,其父類加載器為AppClassLoader使用SandboxClassLoader反射加載並實例化sandbox-core.jar裡的com.alibaba.jvm.sandbox.core.CoreConfigure,傳入第1步的參數以及sandbox.properties文件的路徑
  • JVM層面的切面實現 : jvm-sandbox 之 <事件機制>
    1.觀察者模式觀察者模式的簡單示意如下:EventListenerHandler位於sandbox-core.jar中,通過Spy.spyMethodOnBefore,將流程傳到了EventListenerHandler,傳遞的參數如下:public static Ret spyMethodOnBefore(final Object[] argumentArray,//參數列表
  • JVM:可視化 JVM 故障處理工具
    at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304) at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140) at sun.jvm.hotspot.HSDB.attach(HSDB.java:1184) at sun.jvm.hotspot.HSDB.access
  • k8s pod自動重啟原因(jvm內存設置)
    k8s集群環境下,docker容器中運行鏡像方式啟動springboot項目。由於製作的鏡像未對JVM的內存進行配置,那麼 JVM 會默認設置堆棧的大小,這個大小是根據物理機的內存進行分配的。 那麼物理機的內存越大,默認分配的內存就越大(最大堆棧=1/4 * 物理機內存,初始堆棧=1/64 * 物理機內存)。
  • Github上都在瘋找的京東內部「JVM調優筆記」終於來了
    3、面對JVM的海量參數jvm與性能優化知識點 JVM & GC基礎知識JVM是Java語言可以跨平臺、保持高發展的根本,沒有了JVM,Java語言將失去運行環境。針對Java程序的性能優化一定不可能避免針對JVM的調優,隨著JVM的不斷發展,我們的應對措施也在不斷地跟隨、變化,內存的使用逐漸變得越來越複雜。所有高級語言都需要垃圾回收機制的保護,所以GC就是這麼重要。
  • 面試必問億級流量優化策略之JVM調優,文檔視頻面試,還不收藏
    內存突然被打滿,接口響應時間過長線上系統突然卡死無法訪問,頻繁收到GC報警線上系統突然內存溢出OOM,內存洩露無法定位線上生產環境不知道如何設置JVM各種參數線上系統SQL執行緩慢導致系統接口超時線上資料庫Mysql並發過高導致死鎖線上資料庫Mysql莫名抖動無法定位
  • JVM、GC 大串講,面試夠用了
    引用計數給對象中添加引用計數器,每次被引用都+1,當引用失效就-1,當gc的時候,引用為0,就會被當作垃圾回收掉。優點:實現簡單,判斷效率高。缺點:很難解決對象之間循環引用的問題。也就是因為這個缺點,主流的jvm不選用這種計數法。根可達 root searching就是從「GC Roots」對象作為起點開始往下搜索,搜索所有的「葉子」。
  • 大白話談JVM的class類加載機制
    如果懂得了JVM的運行原理和內存模型,像是一些JVM調優、垃圾回收機制等等的問題我們才能有一個更清晰的概念。為了走進JVM,深入了解底層,王子打算寫一個JVM的專題,留下自己對JVM探索的足跡,同時也希望能幫到小夥伴們更好的理解JVM。那我們開始吧。