91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM的知識點有哪些

發布時間:2021-10-23 15:48:30 來源:億速云 閱讀:145 作者:iii 欄目:編程語言

這篇文章主要介紹“JVM的知識點有哪些”,在日常操作中,相信很多人在JVM的知識點有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JVM的知識點有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

1、什么是JVM?在哪? 


JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。

百度的解釋云里霧里,對于我們Java程序員,說白了就是:
  • JVM本質上是一個程序,它能識別.class 字節碼文件(里面存放的是我們對.java編譯后產生的二進制代碼),并且能夠解析它的指令,最終調用操作系統上的函數,完成我們想要的操作!


  • 關于Java語言的跨平臺性,就是因為JVM,我們可以將其想象為一個抽象層,只要這個抽象層JVM正確執行了.class文件,就能運行在各種操作系統之上了!這就是一次編譯,多次運行


對于JVM的位置:  
  • JVM是運行在操作系統之上的,它與硬件沒有直接的交互

JVM的知識點有哪些  



2、JVM、JRE、JDK 的關系 


JDK(Java Development Kit):Java開發工具包  

JRE(Java Runtime Environment):Java運行環境

JDK = JRE + javac/java/jar 等指令工具

JRE = JVM + Java基本類庫

JVM的知識點有哪些

3、JVM體系結構 

Java虛擬機主要分為五大模塊:

    • ?類裝載器子系統

    • 運行時數據區

    • 執行引擎

    • 本地方法接口

    • 垃圾收集模塊

    

    JVM的知識點有哪些

  • ?

  • 方法區是一種特殊的堆

  • 棧里面不會有垃圾,用完就彈出了,否則阻塞了main方法

  • 垃圾幾乎都在堆里,所以JVM性能調優%99都針對于堆



4、三種JVM(了解) 


Sun公司   HotSpot  (我們都用的這個)

JVM的知識點有哪些

BEA公司   JRockit
IBM公司   J9 VM

5、類加載器  


作用:加載  .Class  字節碼文件

1、回顧new對象的過程

public class Student {
    //私有屬性
    private String name;

    //構造方法
    public Student(String name) {
        this.name = name;
    }
}

類是模板、模板是抽象的;對象是具體的,是對抽象的實例化

//運行時,JVM將Test的信息放入方法區
public class Test{
    //main方法本身放入方法區
  public static void main(String[] args){
        //s1、s2、s3為不同對象
        Student s1 = new Student("zsr");  //引用放在棧里,具體的實例放在堆里
        Student s2 = new Student("gcc");
        Student s3 = new Student("BareTH");
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
        //class1、class2、class3為同一個對象
        Class<? extends Student> class1 = s1.getClass();
        Class<? extends Student> class2 = s2.getClass();
        Class<? extends Student> class3 = s3.getClass();
        System.out.println(class1.hashCode());
        System.out.println(class2.hashCode());
        System.out.println(class3.hashCode());
    }
}
根據結果,我們發現:

    • ?s1、s2、s3的hashcode是不同的,因為是三個不同的對象,對象是具體的



    • class1、class2、class3的hashcode是相同的,因為這是類模板,模板是抽象的

我們畫圖分析以下  new一個對象的流程:
  1. 首先Class Loader讀取字節碼.class文件,加載初始化生成Student模板類


  2. 通過Student模板類new出三個對象

JVM的知識點有哪些

?
那么Class Loader具體是怎么執行我們的.class字節碼文件呢,這就引出了我們類加載器~

2、類加載器的類別

我們編寫這樣一個程序

JVM的知識點有哪些


根據返回結果,我們來講解以下三種加載器:

級別從高到底

1.啟動類(根)加載器:BootstrapClassLoader
    1. ?c++編寫,加載java核心庫 java.*,構造拓展類加載器應用程序加載器

    2. 根加載器加載拓展類加載器,并且將拓展類加載器的父加載器設置為根加載器

    3. 然后再加載應用程序加載器,應將應用程序加載器的父加載器設置為拓展類加載器

    4. 由于引導類加載器涉及到虛擬機本地實現細節,我們無法直接獲取到啟動類加載器的引用;這就是上面那個程序我們第三個結果為null的原因。

    5. 加載文件存在位置



JVM的知識點有哪些
    
2. 拓展類加載器:PlatformClassLoader
    1. java編寫,加載擴展庫,開發者可以直接使用標準擴展類加載器。

    2. java9之前為ExtClassloader,Java9以后改名為PlatformClassLoader

    3.     加載文件存在位置

?
 JVM的知識點有哪些

3.應用程序加載器:AppClassLoader
             1  .  java  編寫,加載程序所在的目錄
      

        2. 是Java默認的類加載器


4.用戶自定義類加載器:CustomClassLoader
            1  .  java  編寫,用戶自定義的類加載器,可加載指定路徑的  class  文件


6、雙親委派機制 

1、什么是雙親委派機制

    • ?類加載器收到類加載的請求


    • 將這個請求向上委托給父類加載器去完成,一直向上委托,直到根加載器BootstrapClassLoader


    • 根加載器檢查是否能夠加載當前類,能加載就結束,使用當前的加載器;否則就拋出異常,通知子加載器進行加載;自加載器重復該步驟。

2、作用

舉個例子:我們重寫以下java.lang包下的String類

JVM的知識點有哪些


發現報錯了,這就是  雙親委派機制  起的作用,當類加載器委托到  根加載器  的時候,  String類  已經被  根加載器  加載過一遍了,所以不會再加載,從一定程度上防止了危險代碼的植入!!
作用總結:
  1. 1.  防止重復加載同一個


  2. .class

  3. 。通過不斷委托父加載器直到根加載器,如果父加載器加載過了,就不用再加載一遍。保證數據安全。



  4. 2. 保證系統核心.class,如上述的String類不能被篡改。通過委托方式,不會去篡改核心.class,即使篡改也不會去加載,即使加載也不會是同一個.class對象了。不同的加載器加載同一個.class也不是同一個class對象。這樣保證了class執行安全。


    

7、沙箱安全機制 

這里引用了這篇博文引用鏈接,了解即    

什么是沙箱?

Java安全模型的核心就是Java沙箱(sandbox)


    1. 沙箱是一個限制程序運行的環境。沙箱機制就是將 Java 代碼限定在虛擬機(JVM)特定的運行范圍中,并且嚴格限制代碼對本地系統資源訪問,通過這樣的措施來保證對代碼的有效隔離,防止對本地系統造成破壞。


    沙箱主要限制系統資源訪問,系統資源包括CPU、內存、文件系統、網絡。不同級別的沙箱對這些資源訪問的限制也可以不一樣。


所有的Java程序運行都可以指定沙箱,可以定制安全策略。

java中的安全模型演進

在Java中將執行程序分成  本地代碼  和  遠程代碼  兩種
  • 本地代碼可信任,可以訪問一切本地資源。

  • 遠程代碼不可信信在早期的Java實現中,安全依賴于沙箱 (Sandbox) 機制。

如下圖所示

JVM的知識點有哪些

如此嚴格的安全機制也給程序的功能擴展帶來障礙,比如當用戶希望遠程代碼訪問本地系統的文件時候,就無法實現。
因此在后續的   Java1.1   版本中,針對安全機制做了改進,增加了  安全策略  ,允許用戶指定代碼對本地資源的訪問權限。
如下圖所示
JVM的知識點有哪些
在  Java1.2  版本中,再次改進了安全機制,增加了  代碼簽名  。
  • 不論本地代碼或是遠程代碼,都會按照用戶的安全策略設定,由類加載器加載到虛擬機中權限不同的運行空間,來實現差異化的代碼執行權限控制。

如下圖所示
JVM的知識點有哪些  JVM的知識點有哪些?  

當前最新的安全機制實現,則引入了  域 (Domain)   的概念。
  • 虛擬機會把所有代碼加載到不同的系統域應用域

  • 系統域部分專門負責與關鍵資源進行交互

  • 應用域部分則通過系統域的部分代理來對各種需要的資源進行訪問。

  • 虛擬機中不同的受保護域 (Protected Domain),對應不一樣的權限 (Permission)。存在于不同域中的類文件就具有了當前域的全部權限,如下圖所示

JVM的知識點有哪些

組成沙箱的基本組件

1. 字節碼校驗器(bytecode verifier)

確保Java類文件遵循Java語言規范。這樣可以幫助Java程序實現內存保護。但并不是所有的類文件都會經過字節碼校驗,比如核心類(如上述java.lang.String)。

2. 類裝載器(class loader)

其中類裝載器在3個方面對Java沙箱起作用
  • 它防止惡意代碼去干涉善意的代碼;

  • 它守護了被信任的類庫邊界;

  • 它將代碼歸入保護域,確定了代碼可以進行哪些操作。

虛擬機為不同的類加載器載入的類提供不同的命名空間,命名空間由一系列唯一的名稱組成,每一個被裝載的類將有一個名字,這個命名空間是由Java虛擬機為每一個類裝載器維護的,它們互相之間甚至不可見。
類裝載器采用的機制是雙親委派模式。  
  1. 從最內層JVM自帶類加載器開始加載,外層惡意同名類得不到加載從而無法使用;


  2. 由于嚴格通過包來區分了訪問域,外層惡意的類通過內置代碼也無法獲得權限訪問到內層類,破壞代碼就自然無法生效。


  • 存取控制器(access controller):存取控制器可以控制核心API對操作系統的存取權限,而這個控制的策略設定,可以由用戶指定。

  • 安全管理器(security manager):是核心API和操作系統之間的主要接口。實現權限控制,比存取控制器優先級高。

  • 安全軟件包(security package):java.security下的類和擴展包下的類,允許用戶為自己的應用增加新的安全特性,包括:


    1. 安全提供者

    2. 消息摘要

    3. 數字簽名

    4. 加密

    5. 鑒別


8、Native本地方法接口 

JNI:Java Native Interface

本地接口的作用是融合不同的編程語言為Java所用,它的初衷是融合C/C++程序

JVM的知識點有哪些

native  :凡是帶native關鍵字的,說明java的作用范圍達不到了,會去調用底層c語言的庫!進入本地方法棧,調用  本地方法接口JNI  ,拓展Java的使用,融合不同的語言為Java所用
    • Java誕生的時候C、C++橫行,為了立足,必須要能調用C、C++的程序


    • 于是在內存區域中專門開辟了一塊標記區域:Native Method Stack,登記Native方法


    • 最終在執行引擎執行的的時候通過JNI(本地方法接口)加載本地方法庫的方法


目前該方法使用的越來越少了,除非是與硬件有關的應用,比如通過Java程序驅動打印機或者Java系統管理生產設備,在企業級應用中已經比較少見。因為現在的異構領域間通信很發達,比如可以使用 Socket通信,也可以使用 Web service等等,了解即可!


9、PC寄存器  

程序計數器  :Program Counter Register
    • 每個線程都有一個程序計數器,是線程私有的,就是一個指針,指向方法區中的方法字節碼(用來存儲指向像一條指令的地址,也即將要執行的指令代碼),在執行引擎讀取下一條指令,是一個非常小的內存空間,幾乎可以忽略不計


10、方法區 

方法區  :Method Area
  • 方法區是被所有線程共享,所有字段和方法字節碼,以及一些特殊方法,如構造函數,接口代碼也在此定義,簡單說,所有定義的方法的信息都保存在該區域,此區域屬于共享區間


  • 方法區與Java堆一樣,是各個線程共享的內存區域,用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。雖然Java 虛擬機規范把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做Non-Heap(非堆),目的應該是與Java 堆區分開來。


1. 方法區中有啥?

  1. 靜態變量(static)

  2. 常量(final)

  3. 類信息(構造方法、接口定義)

  4. 運行時的常量池

2. 創建對象內存分析

JVM的知識點有哪些
JVM的知識點有哪些

  • 創建一個對象時,方法區中會生成對應類的抽象模板;還有對應的常量池、靜態變量、類信息、常量


  • 我們通過類模板去new對象的時候


    • 堆中存放實例對象

    • 棧中存放對象的引用,每個對象對應一個地址指向堆中相同地址的實例對象


例如這個例子中,生成了對應的Person模板類,name常量“zsr”放在常量池中,三個對象的引用放在棧中,該引用指向放在堆中的三個實例對象。
這就是堆、棧、方法區的交互關系

11、棧  

又稱  棧內存  ,主管程序的運行,生命周期和線程同步,線程結束,棧內存就釋放了,  不存在垃圾回收
  • 棧:先進后出

  • 隊列:先進先出(FIFO)

1、棧中存放啥?

  1. 8大基本類型

  2. 對象引用

  3. 實例的方法

2、棧運行原理

  • 棧表示Java方法執行的內存模型


  • 每調用一個方法就會為每個方法生成一個棧幀(Stack Frame),每個方法被調用和完成的過程,都對應一個棧幀從虛擬機棧上入棧和出棧的過程。


  • 程序正在執行的方法一定在棧的頂部


JVM的知識點有哪些

3、堆棧溢出StackOverflowError

舉個例子:

public class Test {
    public static void main(String[] args) {
        new Test().a();
    }

    public void a() {
        b();
    }

    public void b() {
        a();
    }
}


最開始,main()方法壓入棧中,然后執行a(),a()壓入棧中;再調用b(),b()壓入棧中;以此往復,a與b方法不斷被壓入棧中,最終導致棧溢出

JVM的知識點有哪些

JVM的知識點有哪些

12、堆  

Heap,一個JVM只有一個堆內存(棧是線程級的),堆內存的大小是可以調節的

JVM的知識點有哪些

1、堆中有啥?

實例化的對象

2、堆內存詳解

JVM的知識點有哪些

1、Young 年輕代

對象誕生、成長甚至死亡的區

  • Eden Space(伊甸園區):所有的對象都是在此new出來的

  • Survivor Space(幸存區)

    • 幸存0區From Space)(動態的,From和To會互相交換)

    • 幸存1區To Space


Eden區占大容量,Survivor兩個區占小容量,默認比例是8:1:1

2、Tenured 老年代

3、Perm 元空間

存儲的是Java運行時的一些環境或類信息,這個區域不存在垃圾回收!關閉虛擬機就會釋放這個區域內存!

這個區域常駐內存,用來存放JDK自身攜帶的Class對象、Interface元數據。

名稱演變
  • jdk1.6之前:永久代


  • jdk1.7:永久代慢慢退化,去永久代


  • jdk1.8之后:永久代改名為元空間

注意:元空間在邏輯上存在,在物理上不存在
新生代 + 老年代的內存空間 = JVM分配的總內存
如圖所示:

JVM的知識點有哪些

3、什么是OOM?

內存溢出java.lang.OutOfMemoryError

產生原因:
  1. 分配的太少

  2. 用的太多

  3. 用完沒釋放

4、GC垃圾回收

GC垃圾回收,主要在年輕代和老年代

首先,對象出生再  伊甸園區
  • 假設伊甸園區只能存一定數量的對象,則每當存滿時就會觸發一次輕GC(Minor GC)


  • 輕GC清理后,有的對象可能還存在引用,就活下來了,活下來的對象就進入幸存區;有的對象沒用了,就被GC清理掉了;每次輕GC都會使得伊甸園區為空



  • 如果幸存區伊甸園都滿了,則會進入老年代,如果老年代滿了,就會觸發一次重GC(FullGC)年輕代+老年代的對象都會清理一次,活下的對象就進入老年代


  • 如果新生代老年代都滿了,則OOM

Minor GC:伊甸園區滿時觸發;從年輕代回收內存
Full GC:老年代滿時觸發;清理整個堆空間,包含年輕代和老年代
Major GC:清理老年代

什么情況永久區會崩?
一個啟動類加載了大量的第三方Jar包,Tomcat部署了過多應用,或者大量動態生成的反射類
這些東西不斷的被加載,直到內存滿,就會出現  OOM

13、堆內存調優 

1、查看并設置JVM堆內存

查看我們jvm的  堆內存

public class Test {
    public static void main(String[] args) {
        //返回jvm試圖使用的最大內存
        long max = Runtime.getRuntime().maxMemory();
        //返回jvm的初始化內存
        long total = Runtime.getRuntime().totalMemory();
        //默認情況下:分配的總內存為電腦內存的1/4,初始化內存為電腦內存的1/64
        System.out.println("max=" + max / (double) 1024 / 1024 / 1024 + "G");
        System.out.println("total=" + total / (double) 1024 / 1024 / 1024 + "G");
    }
}

JVM的知識點有哪些

JVM的知識點有哪些

默認情況下:
  • JVM最大分配內存為電腦內存的1/4

  • JVM初始化內存為電腦內存的1/64

我們可以手動調堆內存大小

JVM的知識點有哪些

在  VM options  中可以指定  jvm試圖使用的最大內存  和  jvm初始化內存  大小
  
  
  -Xms1024m -Xmx1024m -Xlog:gc*
  • -Xmx用來設置jvm試圖使用的最大內存,默認為1/4

  • -Xms用來設置jvm初始化內存,默認為1/64

  • -Xlog:gc*用來打印GC垃圾回收信息

JVM的知識點有哪些

JVM的知識點有哪些


2、怎么排除OOM錯誤?

1. 嘗試擴大堆內存看結果

利用上述方法指定jvm試圖使用的最大內存jvm初始化內存大小

2. 利用內存快照工具JProfiler

內存快照工具:
  • MAT(Eclipse)

  • JProfiler

作用:
  • 分析Dump內存文件,快速定位內存泄漏

  • 獲得堆中的文件

  • 獲得大的對象

3. 什么是Dump文件?如何分析?

Dump文件是進程內存鏡像,可以把程序的執行狀態通過調試器保存到dump文件中

import java.util.ArrayList;

public class Test {
    byte[] array = new byte[1024 * 1024];//1M

    public static void main(String[] args) {
        ArrayList<Test> list = new ArrayList<>();
        int count = 0;
        try {
            while (true) {
                list.add(new Test());
                count++;
            }
        } catch (Exception e) {
            System.out.println("count=" + count);
            e.printStackTrace();
        }
    }
}

運行該程序,報錯OOM

JVM的知識點有哪些

接下來我們設置以下堆內存,并附加生成對應的dump文件的指令

-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError

-XX:+HeapDumpOnOutOfMemoryError  表示當JVM發生OOM時,自動生成DUMP文件。

再次點擊運行,下載了對應的Dump文件

JVM的知識點有哪些

我們右鍵該類,點擊  Show in Explorer

JVM的知識點有哪些

一直點擊上級目錄,直到找到.hprof文件,與src同級目錄下

JVM的知識點有哪些

我們雙擊打開,可以看到每塊所占的大小,便于分析問題

JVM的知識點有哪些

點擊Thread Dump,里面是所有的線程,點擊對應的線程可以看到相應的錯誤,反饋到具體的行,便于排錯

JVM的知識點有哪些

每次打開Dump文件查看完后,建議刪除,可以在idea中看到,打開文件后生成了很多內容,占內存,建議刪除

JVM的知識點有哪些


附:安裝Jprofiler教程

1.idea中安裝插件
JVM的知識點有哪些
2.下載客戶端 https://www.ej-technologies.com/download/jprofiler/files

JVM的知識點有哪些

3.安裝客戶端
選擇自定義安裝,注意:路徑不能有中文和空格
JVM的知識點有哪些

JVM的知識點有哪些

這里name和Company任意,License Key大家可以尋找對應版本的注冊機獲得

JVM的知識點有哪些

JVM的知識點有哪些

后續默認,安裝成功即可!!!
4. 安裝完成后,重啟IDEA,可以看到我們的內存快照工具
JVM的知識點有哪些

 打開IDEA的設置,找到Tools里面的JProfiler,沒有設置位置則設置位置

JVM的知識點有哪些

此時則全部安裝完成!

14、GC垃圾回收 

1、回顧

Garbage Collection:垃圾回收

JVM的知識點有哪些

在12.4中,我們已經對GC的流程進行了大概的講解,這里做一些總結:
  • JVM在進行GC時,并不是對年輕代老年代統一回收;大部分時候,回收都是在年輕代

  • GC分為兩種:

    • 輕GC(清理年輕代)

    • 重GC(清理年輕代+老年代)

2、GC算法

1、引用計數算法(很少使用)

  • 每個對象在創建的時候,就給這個對象綁定一個計數器。

  • 每當有一個引用指向該對象時,計數器加一;每當有一個指向它的引用被刪除時,計數器減一。

  • 這樣,當沒有引用指向該對象時,該對象死亡,計數器為0,這時就應該對這個對象進行垃圾回收操作。


 JVM的知識點有哪些

2、復制算法

復制算法主要發生在  年輕代  (   幸存0區   和   幸存1區  )
  • 當Eden區滿的時候,會觸發輕GC,每觸發一次,活的對象就被轉移到幸存區,死的就被GC清理掉了,所以每觸發輕GC時,Eden區就會清空;

  • 對象被轉移到了幸存區,幸存區又分為From SpaceTo Space,這兩塊區域是動態交換的,誰是空的誰就是To Space,然后From Space就會把全部對象轉移到To Space去;

  • 那如果兩塊區域都不為空呢?這就用到了復制算法,其中一個區域會將存活的對象轉移到令一個區域去,然后將自己區域的內存空間清空,這樣該區域為空,又成為了To Space

  • 所以每次觸發輕GC后,Eden區清空,同時To區也清空了,所有的對象都在From區

這也就是幸存0區幸存1區總有一塊為空的原因

JVM的知識點有哪些

好處:沒有內存的碎片(內存集中在一塊)
壞處:
  1. 浪費了內存空間(浪費了幸存區一半空間)

  2. 對象存活率較高的場景下(比如老年代那樣的環境),需要復制的東西太多,效率會下降。

最佳使用環境:對象存活度較低的時候,也就是  年輕代

3、標記–清除算法

為每個對象存儲一個標記位,記錄對象的生存狀態
  1. 標記階段:這個階段內,為每個對象更新標記位,檢查對象是否死亡;

  2. 清除階段:該階段對死亡的對象進行清除,執行 GC 操作。


JVM的知識點有哪些
缺點:兩次掃描嚴重浪費時間,會產生內存碎片
優點:不需要額外的空間

4、標記–整理算法

標記-整理法   是   標記-清除法   的一個改進版。
又叫做   標記-清楚-壓縮法
  1. 標記階段,該算法也將所有對象標記為存活和死亡兩種狀態;

  2. 不同的是,在第二個階段,該算法并沒有直接對死亡的對象進行清理,而是將所有存活的對象整理一下,放到另一處空間,然后把剩下的所有對象全部清除。

JVM的知識點有哪些  
可以進一步優化,在內存碎片不太多的情況下,就繼續標記清除,到達一定量的時候再壓縮.

到此,關于“JVM的知識點有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石城县| 博乐市| 广南县| 晋宁县| 磴口县| 徐水县| 杭州市| 若尔盖县| 瓦房店市| 留坝县| 永济市| 清丰县| 酉阳| 嘉兴市| 灵宝市| 塘沽区| 沈阳市| 红安县| 和静县| 迁西县| 广平县| 调兵山市| 包头市| 饶阳县| 尉氏县| 赣榆县| 阿鲁科尔沁旗| 通州市| 海兴县| 宜兰市| 台北县| 崇州市| 衢州市| 台中县| 连江县| 阳泉市| 仪陇县| 凌海市| 嘉祥县| 公主岭市| 保靖县|