欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:JVM簡單學習

柚子快報邀請碼778899分享:JVM簡單學習

http://yzkb.51969.com/

jvm與字節(jié)碼

jvm只需關注字節(jié)碼文件 jvm由哪些部分構(gòu)成 1.類加載子系統(tǒng),將磁盤中的字節(jié)碼文件加載到方法區(qū)的內(nèi)存空間中 類加載器分兩種:引導類加載器是jvm底層中用C和C++語言寫的

各個默認的類加載器的不同區(qū)別在于 各自默認負責要加載的類的目錄不一樣 比如 BootStrapClassLoader:負責jre/lib 目錄下 ExtClassLoader:負責jre/lib/ext 目錄下 AppClassLoader:負責 classpath目錄下

什么是雙親委派 和 雙親委派的兩大作用

避免類的重復加載防止核心API被篡改

什么是雙親委派機制

雙親委派機制(Parent Delegation Mechanism)是Java中的一種類加載機制。在Java中,類加載器負責加載類的字節(jié)碼并創(chuàng)建對應的Class對象。雙親委派機制是指當一個類加載器收到類加載請求時,它會先將該請求委派給它的父類加載器去嘗試加載。只有當父類加載器無法加載該類時,子類加載器才會嘗試加載。

這種機制的設計目的是為了保證類的加載是有序的,避免重復加載同一個類。Java中的類加載器形成了一個層次結(jié)構(gòu),根加載器(Bootstrap ClassLoader)位于最頂層,它負責加載Java核心類庫。其他加載器如擴展類加載器(Extension ClassLoader)和應用程序類加載器(Application ClassLoader)都有各自的加載范圍和職責。通過雙親委派機制,可以確保類在被加載時,先從上層的加載器開始查找,逐級向下,直到找到所需的類或者無法找到為止。

這種機制的好處是可以避免類的重復加載,提高了類加載的效率和安全性。同時,它也為Java提供了一種擴展機制,允許開發(fā)人員自定義類加載器,實現(xiàn)特定的加載策略。

雙親委派機制的原理

雙親委派機制是Java中的一種類加載機制。其原理如下:

當Java程序需要加載一個類時,首先會委托給當前類加載器的父類加載器進行加載。 父類加載器會按照相同的方式嘗試加載該類。如果父類加載器能夠成功加載該類,則加載過程結(jié)束。 如果父類加載器無法加載該類,則會將加載請求再次委托給它的父類加載器,直到達到頂層的引導類加載器。 引導類加載器是Java虛擬機內(nèi)置的類加載器,它負責加載核心類庫,如java.lang包下的類。 如果引導類加載器也無法加載該類,則會回到初始的類加載器,嘗試使用自身的加載機制加載該類。 如果自身的加載機制仍然無法加載該類,則會拋出ClassNotFoundException異常。

通過這種雙親委派的機制,Java實現(xiàn)了類加載的層次結(jié)構(gòu)。它可以確保類的加載是有序的,避免了重復加載和類的沖突。同時,它也提供了一種安全機制,防止惡意代碼的加載和執(zhí)行。

主要實現(xiàn)在ClassLoader里的loadClass方法

雙親委派主要體現(xiàn)在 ClassLoader#loadClass() 方法中:

PS:每個 ClassLoader 都有如下三個基礎方法:

loadClass()

入口,定義了 加載/尋找 Class 的策略。比如雙親委派,或者其他形式調(diào)用 findClass() 讀入 class 文件,并生成 Class 對象 findClass()

根據(jù) class 名,在當前 ClassLoader 能處理路徑中查找,如果能找到就將 class 文件讀入調(diào)用 defineClass 生成 Class 對象 defineClass()

native 方法將字節(jié)數(shù)組生成 Class 對象

// resolve = false 不進行解析

protected Class loadClass(String name, boolean resolve)

throws ClassNotFoundException

{

synchronized (getClassLoadingLock(name)) {

// 查看該類是否被加載過

Class c = findLoadedClass(name);

if (c == null) {

long t0 = System.nanoTime();

try {

// 獲取當前類父類的加載器

if (parent != null) {

// 使用父類的加載器加載?。?!

// 遞歸

c = parent.loadClass(name, false);

} else {

// 如果 parent 為 null,說明父類加載器為引導類加載器

c = findBootstrapClassOrNull(name);

}

} catch (ClassNotFoundException e) {

}

// 當前類的加載器父類加載器未加載此類 or 當前類的加載器未加載此類

if (c == null) {

long t1 = System.nanoTime();

// 調(diào)用當前 Classloader 的 findClass

// 注:可能當前 classloader 無法處理要加載的這個類的路徑,這時返回 null

c = findClass(name);

// this is the defining class loader; record the stats

sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);

sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

sun.misc.PerfCounter.getFindClasses().increment();

}

}

// 根據(jù)入?yún)Q定是否解析

if (resolve) {

resolveClass(c);

}

return c;

}

}

如何自定義類加載器,下面是一個自定義 ClassLoader 示例,直接繼承 ClassLoader 類,然后重寫 findClass 方法就行了(采用雙親委派)

public class MyClassLoader extends ClassLoader{

// 指定的要加載 class 文件的目錄

private File classPathFile;

public MyClassLoader(String absolutePath) {

this.classPathFile = new File(absolutePath);

}

@Override

// 根據(jù)類名將指定類加載進 JVM

// 注:該 class 必修在指定的 absolutePath 下

protected Class findClass(String name) throws ClassNotFoundException {

// 拼接全類名

String className = MyClassLoader.class.getPackage().getName() + "." + name;

if(classPathFile != null){

// 根據(jù)絕對路徑,以及 class 文件名,拿到 class 文件

// 注意全類名的情況

File classFile = new File(classPathFile,name.replaceAll("\\.","/") + ".class");

// 如果 class 文件存在

if(classFile.exists()){

// 將 class 文件讀入內(nèi)存,暫存到一個字節(jié)數(shù)組中

FileInputStream in = null;

ByteArrayOutputStream out = null;

try{

in = new FileInputStream(classFile);

out = new ByteArrayOutputStream();

byte [] buff = new byte[1024];

int len;

while ((len = in.read(buff)) != -1){

out.write(buff,0,len);

}

// 構(gòu)造類的 Class 對象?。?!

// 注:defineClass() 是一個 native 方法

return defineClass(className, out.toByteArray(), 0, out.size());

}catch (Exception e){

e.printStackTrace();

}

}

}

return null;

}

}

運行時數(shù)據(jù)區(qū)

程序計數(shù)器

Java方法棧

一個方法對應一個棧幀,方法內(nèi)有其他方法就會依次入棧,執(zhí)行完的方法對應的棧幀會出棧

OOM是內(nèi)存不夠, StackOverflowError 是方法調(diào)用層次太多

棧幀

局部變量表

slot 代表各個方法內(nèi)的局部變量

操作數(shù)棧

執(zhí)行步驟

10 壓入操作數(shù)棧將 10 放入局部變量表 2將20 壓入操作數(shù)棧將20 放入局部變量表2iload1 將 局部變量表1放入操作數(shù)棧 iload2 將 局部變量表2放入操作數(shù)棧iadd 操作數(shù)棧中相加,得到的值放入局部變量3

本地方法棧

Java對象在各個區(qū)域的流轉(zhuǎn)情況

對象首先來到Eden區(qū),Eden滿了后進行一次GC,沒被清理的對象來到S0區(qū)計數(shù)加一,Eden迎接新對象,每次GC存活對象計數(shù)加一,計數(shù)達到閾值進入老年代,如果有大對象(文件上傳對象)S0和S1放不下直接進入老年代

各個GC的區(qū)別

老年代只有一個CMS專門回收

為什么要進行垃圾回收

垃圾標記階段,如何標記垃圾

引用計數(shù)法

可達性分析法

GCRoots包括哪些

虛擬機棧和本地方法棧中的方法參數(shù)和局部變量存儲的是對象的地址值

GC算法

標記清除算法

缺點

效率不高會產(chǎn)生內(nèi)存碎片 優(yōu)點

簡單

復制算法

利用空間換時間,適合垃圾對象比較多,非垃圾對象少,這樣復制成本就低效率就高。 新生代適合用復制算法,因為對象朝生夕死

標記整理算法

算法總結(jié)

一種GC算法的使用理念

算法按需使用,用到最適合他的地方

常見的垃圾收集器

CMS 如何工作

并發(fā)標記清除算法,特點低暫停,STW時間短,執(zhí)行過程長,工作線程暫停時間短影響小,所以用戶體驗好,但是吞吐量變低

階段一 初始標記:

STW暫停所有工作線程標記出GCRoots能直接可達對象(以GCRoots為起點的第一層引用對象,不再向下標記)一旦標記,就回復工作線程繼續(xù)執(zhí)行這個階段比較短,所以STW時間短 階段二 并發(fā)標記(最費時的階段,但是不STW不影響工作線程工作): 因為工作線程也在運行中,標記垃圾可能會有誤差,因為程序在運行就有可能產(chǎn)生垃圾對象,但是誤差不大 階段三和階段四 重新標記短暫STW后并發(fā)清理

CMS存在的問題

G1是如何工作的

G1垃圾回收器下,堆空間不再是其他回收器那樣的各個代之間層次分明,而是把堆空間分成2048個Region進行管理,各個代空間邏輯上連續(xù),但是物理上不再連續(xù)

G1的初始標記和并發(fā)標記與CMS相同

G1和CMS最大區(qū)別在最后一步,CMS是清除算法,G1是復制算法,復制到空閑的region

G1的篩選回收

可以指定GC的STW停頓時間,CMS的STW時間是不確定的,相較于CMS的清除算法,G1是把需要清理的Region中的非垃圾對象復制到空閑的Region區(qū)域

柚子快報邀請碼778899分享:JVM簡單學習

http://yzkb.51969.com/

參考閱讀

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權,聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/18939019.html

發(fā)布評論

您暫未設置收款碼

請在主題配置——文章設置里上傳

掃描二維碼手機訪問

文章目錄