成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JVM虛擬機整體結構與對象內存分配解析

云計算 虛擬化
棧是JVM重要的組成部分,每有一個新的線程都JVM都會為其在棧上分配一份內存,線程里有棧幀,程序計數器。

[[414275]]

JVM虛擬機整體結構解析

整體結構介紹

  • jvm整體分為:
  • -棧方法區堆本地方法棧程序計數器

棧 Stack

棧是JVM重要的組成部分,每有一個新的線程都JVM都會為其在棧上分配一份內存,線程里有棧幀,程序計數器。另外線程棧內存大小決定的線程數量的多少,當線程棧內存大小設置的越大,則同時存在的線程數量越少,反則越大。另外在棧中最容易發生的錯誤是StackOverflowError 棧溢出,看以下代碼:

  1. public class StackOverflowTest {  
  2.   static int count = 0; 
  3.    static void redo() {  
  4.    count++;  
  5.     redo();  
  6.     } 
  7.     public static void main(String[] args) {  
  8.      try {  
  9.    redo();  
  10.     } catch (Throwable t) {  
  11.     t.printStackTrace();  
  12.     System.out.println(count);  
  13.            }  
  14.        }  
  15.     }   
  16.      運行結果: 
  17.      java.lang.StackOverflowError  

參數影響: -Xss 256KB(默認1M) 設置棧大小 棧的大小會影響count 的次數,-Xss設置的大小越大,count的次數也就越大,反之亦然.

棧幀結構組成

局部變量表:主要用來保存聲明的局部變量以及方法的參數信息,局部變量表作用于為當前方法,當方法執行完成后,局部變量表也會隨之刪除,釋放內存。另外局部變量表里用來保存信息的叫做變量槽(slot)

操作數棧:顧名思義,操作數棧其本質就是個棧,壓棧,出棧兩個操作,例如執行a+b,先將局部變量表中的a與b分別壓入棧中,接著執行加法操作,最終出棧。

動態鏈接:是在程序運行期間完成的將符號引用替換為直接引用叫動態鏈接,既然有動態鏈接那么自然也有靜態鏈接,部分符號引用在類加載階段(解析)的時候就轉化為直接引用,這種轉化為靜態鏈接。

方法返回地址:在方法退出(正常執行/異常返回)后,返回方法被調用的位置。

棧結構圖

JVM虛擬機整體結構與對象內存分配解析

程序計數器(Program Counter Register)

程序計數器也叫PC寄存器是JVM非常重要的一個結構,是線程私有的,每個線程獨有一份,它用來保存指向下一條將被執行指令的地址,例如當線程被阻塞再進行喚醒時,從程序計數器讀取指令的地址,從而繼續執行。

本地方法棧 Native Method Stack

本地方法棧主要是為了執行native方法,保存native方法進入區域的地址,所以本地方法棧也是線程私有的內存區域。

方法區 Method Area(元空間 Meta Space)

被所有的線程共享。方法區包含所有的class和static變量,類的方法代碼,變量名,方法名,訪問權限,返回值,以及我們經常說的常量池與運行時常量池都是在方法區的。

堆 Heap

堆是非常重要的一個區域,管理著幾乎(不是所有)所有的對象,我們常說的垃圾回收的主要區域就是發生在這個區域。堆分為新生代(young)與老年代(Old),新生代又分為Eden與survivor區,survivor分為From區與To區。這幾個區存放著java的對象,當區內存不夠的時候會發生GC,GC主要分為兩種,一種是minorGC(Young GC),另一種是Full GC,JVM調優主要根據代碼調節JVM參數,從而減少Full GC的次數。

堆結構示意圖

JVM虛擬機整體結構與對象內存分配解析

逃逸分析

首先大家聽得最多的就是new 出來對象是存放在堆中的,但是在上文中,所寫的是幾乎對象是存在堆中,那么為什么是幾乎呢,因為有的對象是存放在棧中的,是不是很不可思議,接下來來看下一段代碼。

  1. // 方法一 
  2. public Person test1() { 
  3.         Person person = new Person(); 
  4.         person.setId(1); 
  5.         return person; 
  6.         }  
  7. // 方法二       
  8. public void test2() {  
  9.          User person = new person();  
  10.          person.setId(1);  
  11.        } 

上述代碼中很顯然test1方法中的personr對象被返回了,那么這個對象就可能被其他方法進行引用,test2方法中的personr對象,當方法結束的時候,該對象就是一個無效對象了,不會在其他地方被進行引用,對于這樣的對象,JVM將其分配的棧內存里,讓其在方法結束時跟隨棧內存一起被回收掉,減少堆內存的回收。 JVM對于這種情況可以通過開啟逃逸分析參數(-XX:+DoEscapeAnalysis)來優化對象內存分配位置,JDK7之后默認開啟逃逸分析,如果要關閉使用參數(-XX:-DoEscapeAnalysis)

對象內存分配

對象內存分配流程圖

JVM虛擬機整體結構與對象內存分配解析

對象棧上分配

并不是所有對象都分配在內存,有的對象會被分配到棧上,JVM對于這種情況可以通過開啟逃逸分析參數(-XX:+DoEscapeAnalysis)來優化對象內存分配位置,使其通過標量替換優 先分配在棧上(棧上分配),JDK7之后默認開啟逃逸分析,如果要關閉使用參數(-XX:-DoEscapeAnalysis)

標量替換: 通過逃逸分析確定該對象不會被外部訪問,并且對象可以被進一步分解時,JVM不會創建該對象,而是將該 對象成員變量分解若干個被這個方法使用的成員變量所代替,這些代替的成員變量在棧幀或寄存器上分配空間,這樣就 不會因為沒有一大塊連續空間導致對象內存不夠分配。

開啟標量替換參數(-XX:+EliminateAllocations),JDK7之后默認 開啟。

標量與聚合量: 標量即不可被進一步分解的量,也可以說是原子量,不可再分解,而JAVA的基本數據類型就是標量(如:int,long等基本數據類型以及 reference類型等),標量的對立就是可以被進一步分解的量,而這種量稱之為聚合量。而在JAVA中對象就是可以被進一 步分解的聚合量

結論:棧上分配依賴于逃逸分析和標量替換

對象在Eden區分配

當對象剛被創建的時候會被分配在eden區,eden區滿了后會觸發minor gc,可能會有99%以上的對象成為垃圾被回收掉,剩余存活 的對象會被挪到為空的那塊survivor區,下一次eden區滿了后又會觸發minor gc,把eden區和survivor區垃圾對象回收,把剩余存活的對象一次性挪動到另外一塊為空的survivor區,因為新生代的對象都是生命值很短的,存活時間很短,所以JVM默認的8:1:1的比例是非常合理的一個比例值,因此我們呢應該讓eden區盡量的大,survivor區夠用即可,

JVM默認有這個參數-XX:+UseAdaptiveSizePolicy(默認開啟),會導致這個8:1:1比例自動變化.

如果不想這個比例有變 化可以設置參數

-XX:-UseAdaptiveSizePolicy

當Eden區內存不夠用了會出現聲明狀況?

如果因為給新對象分配內存的時候eden區內存幾乎已經被分配完了,bane當Eden區沒有足夠空間進行分配時,虛擬機將發起一次Minor GC,GC期間虛擬機又發現新對象無法存入Survior空間,所以只好把新生代的對象提前轉移到老年代中去,老年代上的空間足夠存放新對象,所以不會出現Full GC。執行Minor GC后,后面分配的對象如果能夠存在eden區的話,還是會在eden區分配內存。

大對象直接進入老年代

大對象就是需要大量連續內存空間的對象(比如:字符串、數組)。JVM參數

-XX:PretenureSizeThreshold 可以設置大 對象的大小,如果對象超過設置大小會直接進入老年代,不會進入年輕代,這個參數只在 Serial 和ParNew兩個收集器下 有效(關于收集器日后再講)。

比如設置JVM參數:

-XX:PretenureSizeThreshold=1000000 (單位是字節) -XX:+UseSerialGC ,再執行下帶有大對象的程序會發現大對象直接進了老年代

這樣做的好處?

為了避免為大對象分配內存時的復制操作而降低效率。

長期存活的對象將進入老年代

既然虛擬機采用了分代收集的思想來管理內存,那么內存回收時就必須能識別哪些對象應放在新生代,哪些對象應放在 老年代中。為了做到這一點,虛擬機給每個對象一個對象年齡(Age)計數器。 如果對象在 Eden 出生并經過第一次 Minor GC 后仍然能夠存活,并且能被 Survivor 容納的話,將被移動到 Survivor 空間中,并將對象年齡設為1。對象在 Survivor 中每熬過一次 MinorGC,年齡就增加1歲,當它的年齡增加到一定程度(默認為15歲,CMS收集器默認6歲,不同的垃圾收集器會略微有點不同),就會被晉升到老年代中。對象晉升到老年代

的年齡閾值.

JVM參數設置 -XX:MaxTenuringThreshold 。

對象動態年齡判斷

當前放對象的Survivor區域里(其中一塊區域,放對象的那塊s區),一批對象的總大小大于這塊Survivor區域內存大小的

50%(-XX:TargetSurvivorRatio可以指定),那么此時大于等于這批對象年齡最大值的對象,就可以直接進入老年代了,

例如Survivor區域里現在有一批對象,年齡1+年齡2+年齡n的多個年齡對象總和超過了Survivor區域的50%,此時就會

把年齡n(含)以上的對象都放入老年代。這個規則其實是希望那些可能是長期存活的對象,盡早進入老年代。對象動態年

齡判斷機制一般是在minor gc之后觸發的。

老年代空間分配擔保機制

年輕代每次minor gc之前JVM都會計算下老年代剩余可用空間 如果這個可用空間小于年輕代里現有的所有對象大小之和(包括垃圾對象) 就會看一個“

-XX:-HandlePromotionFailure”(jdk1.8默認就設置了)的參數是否設置了 如果有這個參數,就會看看老年代的可用內存大小,是否大于之前每一次minor gc后進入老年代的對象的平均大小。 如果上一步結果是小于或者之前說的參數沒有設置,那么就會觸發一次Full gc,對老年代和年輕代一起回收一次垃圾, 如果回收完還是沒有足夠空間存放新的對象就會發生"OOM" 當然,如果minor gc之后剩余存活的需要挪動到老年代的對象大小還是大于老年代可用空間,那么也會觸發full gc,full gc完之后如果還是沒有空間放minor gc之后的存活對象,則也會發生“OOM.

總結

  1. 運行時數據區主要由堆、棧、程序計數器、方法區、本地方法棧
  2. 線程私有的區域:線程棧、程序計數器、本地方法棧,線程共享的區域:堆、方法區。
  3. 堆分為細分為新生代(Eden、survivor(From、To)默認比例8:1:1)、老年代
  4. 對象不全都是在堆中,經過發生逃逸符合條件的對象在棧中
  5. JVM整體結構圖如下
JVM虛擬機整體結構與對象內存分配解析

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2011-11-30 14:12:05

JavaJVM虛擬機

2010-09-25 15:13:40

JVMJava虛擬機

2010-09-25 15:59:54

JVM虛擬機

2009-06-04 16:27:39

Java虛擬機JVMGC

2010-09-17 15:12:57

JVMJava虛擬機

2018-04-08 08:45:53

對象內存策略

2011-05-26 15:41:25

java虛擬機

2020-05-08 16:55:48

Java虛擬機JVM

2011-06-22 13:35:55

JVM

2010-09-25 16:12:45

JVM虛擬機

2011-01-26 11:01:37

虛擬機負載管理資源分配

2024-02-21 07:40:17

JVM內存虛擬機

2012-01-11 10:45:57

JavaJVM

2010-02-04 10:05:28

Dalvik虛擬機

2011-12-28 13:24:47

JavaJVM

2017-03-17 09:48:09

DVMJVMAndroid

2014-04-09 14:15:21

虛擬機虛擬機資源

2011-12-28 13:38:00

JavaJVM

2012-05-18 10:22:23

2017-09-20 08:48:09

JVM內存結構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中日字幕大片在线播放 | 一级黄色片日本 | 毛片区| 99热首页 | 亚洲综合大片69999 | 亚洲精品国产a久久久久久 中文字幕一区二区三区四区五区 | 午夜免费网站 | 亚洲午夜网 | 97avcc| 亚洲精品久久久久久国产精华液 | 91精品国产一二三 | 国产成人在线一区二区 | 精品免费 | 99久久国产综合精品麻豆 | 亚洲成在线观看 | 久久精品色欧美aⅴ一区二区 | 亚洲人精品 | 欧美精品一区二区在线观看 | 国产精品色 | 91小视频在线 | 91视频一区二区 | 日韩一区二区三区在线观看 | 国产亚洲精品久久久久久牛牛 | 久久逼逼 | 久久久久91| 色欧美片视频在线观看 | 亚洲一区二区三区四区五区中文 | 日韩免费一区二区 | 四虎网站在线观看 | 国产欧美日韩综合精品一区二区 | 久久这里只有精品首页 | 第四色影音先锋 | 亚洲视频免费观看 | 久久精品视频91 | 精品国产一区二区三区性色 | 欧美精品一区三区 | 精品欧美乱码久久久久久1区2区 | 精品久久久久久久 | 色成人免费网站 | 欧美性生活免费 | 国产福利在线 |