JVM內存調優 - 淺析 20181121

一.引言

  • JVM在整個jdk中處於最底層,負責於操做系統的交互,用來屏蔽操做系統環境,提供一個完整的Java運行環境,所以也叫虛擬計算機。操做系統運行JVM是經過jdk中Java.exe來完成的。
  • 每一個使用Java的開發者都知道Java字節碼是在JRE中運行(JRE: Java 運行時環境)。JVM則是JRE中的核心組成部分,承擔分析和執行Java字節碼的工做,而Java程序員一般並不須要深刻了解JVM運行狀況就能夠開發出大型應用和類庫。
  • java虛擬機(JVM:Java Virtual Machine)是經過軟件模擬物理機器執行程序的執行器。最初Java語言被設計爲基於虛擬機器在而非物理機器,重而實現WORA(一次編寫,處處運行)的目的,儘管這個目標幾乎被世人所遺忘。因此,JVM能夠在全部的硬件環境上執行Java字節碼而無須調整Java的執行模式。

二.內存結構

1.方法區 也稱永久代java

  • 存放 類的信息,常量,靜態變量
  • 各線程共享

2.棧空間程序員

  • 存放局部變量,操做棧,方法出口等信息 (spring單例安全)
  • 線程私有
  • 棧幀固定大小分配,異常棧溢出

3.堆空間 也稱「gc」web

  • 存放 對象實例及數組
  • 線程共享
  • 在JVM啓動時建立

4.程序計數器算法

  • 做用:當前線程所執行的字節碼的行號指示器
  • 字節碼解釋器工做時就是經過改變這個計數器的值來選取下一條須要執行的字節碼指令,分支,循環,異常處理
  • 線程恢復等基礎功能

三.JVM代劃分

  • 年輕代(Young Generation)
  • 老年代(Old Generation)
  • 永久代(Permanent Generation)

Heap(堆) = 年輕代 (eden + survivor1 + survivor2) + 老年代spring

四.觸發GC和Full GC

  • GC: 通常狀況下,當新對象生成,且在Eden申請空間失敗時,就會觸發GC
  • Full GC:
    年老代寫滿
    永久代寫滿
    System.gc()被顯式調用

五.垃圾回收算法

  1. Mark-Sweep(標記 - 清除)算法
      它是最基礎的垃圾回收算法,其餘算法都是基於這種思想。標記-清除算法分爲「標記」,「清除」兩個階段:首先標記出須要回收的對象,標記完成後統一清除對象
    在這裏插入圖片描述
    缺點:
      ①:標記和清除的效率不高
      ②:標記以後會產生大量不連續的內存碎片數組

  2. Coping(複製)算法
      它將可用內存分爲兩塊,每次只用其中的一塊,當這塊內存用完之後,將還存活的對象複製到另外一塊上面,而後再把已經使用的內存空間一次清理掉
    在這裏插入圖片描述
    優勢:
      ①:不會產生內存碎片
      ②:只要移動堆頂的指針,按順序分配內存便可,實現簡單,運行高效
    缺點:
      ①:內存縮小爲原來的一半安全

  3. Mark-Compact(標記 - 整理)算法
      標記操做和」標記-清除「算法同樣,後續操做變成不直接清理對象,而是在清理無用對象的時候完成讓全部存活的對象都像一端移動,並更新對象的指針
    在這裏插入圖片描述
     優勢:不會產生內存碎片
     缺點:在「標記-清除」基礎上還要進行對象的移動,成本相對較高併發

  4. Generational Collection(分代收集)算法
      是目前大部分JVM的垃圾收集器採用的算法。它的核心思想是根據對象存活的生命週期將內存劃分爲若干個不一樣的區域。通常狀況下將堆區劃分爲老年代(Tenured Generation)和新生代(Young Generation),老年代的特色是每次垃圾收集時只有少許對象須要被回收,而新生代的特色是每次垃圾回收時都有大量的對象須要被回收,那麼就能夠根據不一樣代的特色採起最適合的收集算法。
      目前大部分垃圾收集器對於新生代都採起Copying算法,由於新生代中每次垃圾回收都要回收大部分對象,也就是說須要複製的操做次數較少,可是實際中並非按照1:1的比例來劃分新生代的空間的,通常來講是將新生代劃分爲一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden空間和其中的一塊Survivor空間,當進行回收時,將Eden和Survivor中還存活的對象複製到另外一塊Survivor空間中,而後清理掉Eden和剛纔使用過的Survivor空間而因爲老年代的特色是每次回收都只回收少許對象,通常使用的是Mark-Compact算法。
      注意,在堆區以外還有一個代就是永久代(Permanet Generation),它用來存儲class類、常量、方法描述等。對永久代的回收主要回收兩部份內容:廢棄常量和無用的類。jvm

六.優化參數配置

一、 堆設置
-Xms:初始堆大小svg

-Xmx:最大堆大小

-XX:NewSize=n:設置年輕代大小 -XX:NewSize=3

-XX:NewRatio=n:設置年輕代和年老代的比值。如:爲3,表示年輕代與年老代比值爲1:3,年輕代佔整個年輕代年老代和的1/4

-XX:SurvivorRatio=3
-XX:SurvivorRatio=n:年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區佔整個年輕代的1/5 3:1:1

-XX:MaxPermSize=n:設置永久代大小

二、 收集器設置
-XX:+UseSerialGC:設置串行收集器

-XX:+UseParallelGC:設置並行收集器

-XX:+UseParalledlOldGC:設置並行年老代收集器

-XX:+UseConcMarkSweepGC:設置併發收集器

-XX:+UseG1GC 設置G1收集器

三、 垃圾回收統計信息
-verbose:gc

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

四、 並行收集器設置
-XX:ParallelGCThreads=n:設置並行收集器收集時使用的CPU數。並行收集線程數。

-XX:MaxGCPauseMillis=n:設置並行收集最大暫停時間

-XX:GCTimeRatio=n:設置垃圾回收時間佔程序運行時間的百分比。公式爲1/(1+n)

五、 併發收集器設置
-XX:+CMSIncrementalMode:設置爲增量模式。適用於單CPU狀況。
-XX:ParallelGCThreads=n:設置併發收集器年輕代收集方式爲並行收集時,使用的CPU數。並行收集線程數。

七.優化工具的啓動虛擬機

一、 打開工具的.ini加入以下配置
-verbose:gc
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:D:\jvm.log

二、 查看jvm.log文件 查看觸發了Gc Full Gc 三、 更改配置 -Xms3096m 設置堆最小空間 -Xmx3096m 設置堆最大空間 -XX:MaxPermSize=256m 設置永久代空間

相關文章
相關標籤/搜索