1.JVM運行時數據區

JVM運行時數據區

概述:本文爲JVM系列教程的第一課,主要陳述Java運行時數據區模型,及各個部分的作用。
附加知識點

  1. intern()方法講解
  2. String,Integer,int的==問題
    在我第一次實習面試騰訊時,面試官問的問題就有JVM,在那時,我想學這個有什麼用,後面我一步步瞭解了JVM,仍然感覺這東西很虛,但是,現在,我想我們需要改變態度,因爲JVM真的有很多的使用價值,比如線上排查問題等等

JVM
內存數據區域:線程共享區+線程獨享區
線程共享:java堆+方法區
線程獨享:java虛擬機棧+程序計數器+本地方法棧
JVM內存模型
線程共享區會發生多線程併發的問題,注意,這並不是本文的重點,不過讀者可訪問我的多線程併發的文章

1.程序計數器

程序計數器
是什麼:是程序運行的指針,用於標誌和引導java代碼的執行順序,以及線程上下文切換後正確恢復至上次運行狀態
爲什麼:爲了線程能夠正確恢復,所以需要
特點:唯一一個不會發生OOM(OutOfMemoryError的一塊區域)

2.Java虛擬機棧

是什麼:java方法執行的內存模型,用於存放局部變量表,操作數棧,動態鏈接,方法返回類型
那什麼是局部變量表,局部變量表包括八種基本數據類型+reference(存放的對象引用,可能是直接引用,也有可能存放的是對象的句柄)
操作數棧:方法進行的運算,用操作數棧來保留結果
動態鏈接:不瞭解,也不重要
方法返回類型:很容易理解
注意:當虛擬機棧的棧幀數量超過虛擬機的規定時,會發生StackOverFlowError錯誤。

3.本地方法棧

與Java虛擬機棧相同,只不過它是爲本地方法提供服務
存儲的類型均一樣,也會發生StackOverFlowError錯誤
注意:HotSpot將本地方法棧+虛擬機棧合二爲一

4.方法區

注意:不要因文生意
是什麼:方法區並不是Java方法執行的內存模型,java虛擬機棧纔是,方法區是存放類信息,常量,靜態變量和編譯後的代碼的一塊區域
需要注意的是它有常量池。這樣會引發String == 問題,後文轉述此問題

5.Java堆

用於存放具體的對象,以及數組
又分爲兩個區:新生代,老年代
是垃圾回收的主要區域,我將此用了一片完整的博客專門陳述,包括垃圾回收算法,垃圾回收器,minorGC ,FullGC等等。

6.堆外內存

直接內存:受本機內存的影響,也會發生OOM,當heap利用率很低但發生OOM時需要考慮這個問題
好了,現在我們開始講述 String == int,Integer == 問題吧

public class FinalDemo {
    public static void main(String[] args) {
        String a = "abc";//分配在常量池中
        String b = "abc";//分配在常量池中
        String c = "a"+"bc";////分配在常量池中
        String e = "a";//分配在常量池中
        String d = e+"bc";//分配在堆中,只要有變量就在堆中

        String str = new String("abc");//分配在堆中
        System.out.println("begin");
        System.out.println(a==b);//true
        System.out.println(a==str);//false
        System.out.println(str.intern()==a);//true,因爲intern()會檢查常量池中是否存在,
        //不存在則往常量池中存儲一個,然後返回此引用。
        System.out.println(a==d);//false
        System.out.println(a==c);//true

    }
}
注意:原則1.只要分配在堆中,就一定不相等,但是在常量池中就一定相等
		   原則2.String d = e+"bc";//存在變量,分配在堆中
		  			 String str = new String("abc");//new分配在堆中
		  intern():比較的是常量池引用	
		  System.out.println(str.intern()==a);//true,因爲intern()會檢查常量池中是否存在,
        //不存在則往常量池中存儲一個,然後返回此引用。

上面是String的==,現在說說Integer的==方法,

public class FinalDemo {
    public static void main(String[] args) {
        Integer num1 = 10;
        int int1 = 10;
        Integer num2 = 10;
        Integer integer2 = new Integer(10);
        System.out.println(num1 == num2);//true,因爲存在緩衝區
        System.out.println(num1 == int1);//自動拆裝,true
        System.out.println(integer2 == num2);//一個在緩存區,一個在堆,所以false
        Integer integer3 = 128;
        Integer integer4 = 128;
        System.out.println(integer3 == integer4);//false,緩存區只會緩存-128到127的
        }
  }
  
     

下一篇:對象的產生及垃圾回收算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章