java虛擬機

jvm的內存模型

jvm的內存模型在1.7和1.8有較大的區別,雖然本套課程是以1.8爲例進行講解,但是我們也是需要對1.7的內存模
型有所瞭解,所以接下里,我們將先學習1.7再學習1.8的內存模型。

jdk1.7的堆內存模型

在這裏插入圖片描述

  • Young 年輕區(代)
    Young區被劃分爲三部分,Eden區和兩個大小嚴格相同的Survivor區,其中,Survivor區間中,某一時刻只有其中一個是被使用的,另外一個留做垃圾收集時複製對象用,在Eden區間變滿的時候, GC就會將存活的對象移到空閒的Survivor區間中,根據JVM的策略,在經過幾次垃圾收集後,任然存活於Survivor的對象將被移動到Tenured區間。

  • Tenured 年老區
    Tenured區主要保存生命週期長的對象,一般是一些老的對象,當一些對象在Young複製轉移一定的次數以後,對象就會被轉移到Tenured區,一般如果系統中用了application級別的緩存,緩存中的對象往往會被轉移到這一區間。

  • Perm 永久區
    Perm代主要保存class,method,filed對象,這部份的空間一般不會溢出,除非一次性加載了很多的類,不過在涉及到熱部署的應用服務器的時候,有時候會遇到java.lang.OutOfMemoryError : PermGen space 的錯誤,造成這個錯誤的很大原因就有可能是每次都重新部署,但是重新部署後,類的class沒有被卸載掉,這樣就造成了大量的class對象保存在了perm中,這種情況下,一般重新啓動應用服務器可以解決問題。

  • Virtual區:
    最大內存和初始內存的差值,就是Virtual區。

jdk1.8的堆內存模型

在這裏插入圖片描述
由上圖可以看出,jdk1.8的內存模型是由2部分組成,年輕代 + 年老代。

年輕代:Eden + 2*Survivor

年老代:OldGen

在jdk1.8中變化最大的Perm區,用Metaspace(元數據空間)進行了替換。

需要特別說明的是:Metaspace所佔用的內存空間不是在虛擬機內部,而是在本地內存空間中,這也是與1.7的永久代最大的區別所在。
在這裏插入圖片描述

爲什麼要廢棄1.7中的永久區?

官網給出瞭解釋:http://openjdk.java.net/jeps/122

This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.

移除永久代是爲融合HotSpot JVM與 JRockit VM而做出的努力,因爲JRockit沒有永久代,不需要配置永久代。
現實使用中,由於永久代內存經常不夠用或發生內存泄露,爆出異常java.lang.OutOfMemoryError: PermGen。

基於此,將永久區廢棄,而改用元空間,改爲了使用本地內存空間。

通過jstat命令進行查看堆內存使用情況

jstat命令可以查看堆內存各部分的使用量,以及加載類的數量。命令的格式如下:

jstat [-命令選項] [vmid] [間隔時間/毫秒] [查詢次數]

查看class加載統計

在這裏插入圖片描述

說明:

  • Loaded:加載class的數量
  • Bytes:所佔用空間大小
  • Unloaded:未加載數量
  • Bytes:未加載佔用空間
  • Time:時間

查看編譯統計

在這裏插入圖片描述
說明:

  • Compiled:編譯數量。
  • Failed:失敗數量
  • Invalid:不可用數量
  • Time:時間
  • FailedType:失敗類型
  • FailedMethod:失敗的方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章