日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ftpwebrequest 无法加载或初始化请求的服务提供程序_jvm之类加载机制

發(fā)布時(shí)間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ftpwebrequest 无法加载或初始化请求的服务提供程序_jvm之类加载机制 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是類加載

每個(gè)編寫的".java"拓展名類文件都存儲(chǔ)著需要執(zhí)行的程序邏輯,這些".java"文件經(jīng)過Java編譯器編譯成拓展名為".class"的文件,".class"文件中保存著Java代碼經(jīng)轉(zhuǎn)換后的虛擬機(jī)指令,當(dāng)需要使用某個(gè)類時(shí),虛擬機(jī)將會(huì)加載它的".class"文件,并創(chuàng)建對應(yīng)的class對象,將class文件加載到虛擬機(jī)的內(nèi)存,這個(gè)過程稱為類加載。

類加載的生命周期

如圖所示,JVM類加載機(jī)制分為五個(gè)部分:加載,驗(yàn)證,準(zhǔn)備,解析,初始化。

加載

加載階段是類加載過程的第一個(gè)階段。在這個(gè)階段,JVM 的主要目的是將字節(jié)碼從各個(gè)位置(網(wǎng)絡(luò)、磁盤等)轉(zhuǎn)化為二進(jìn)制字節(jié)流加載到內(nèi)存中,接著會(huì)為這個(gè)類在 JVM 的方法區(qū)創(chuàng)建一個(gè)對應(yīng)的 Class 對象,這個(gè) Class 對象就是這個(gè)類各種數(shù)據(jù)的訪問入口。

驗(yàn)證

驗(yàn)證是連接階段的第一步,這一階段的目的是為了確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全。驗(yàn)證階段大致會(huì)完成4個(gè)階段的檢驗(yàn)動(dòng)作:

  • 文件格式驗(yàn)證:驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范;例如:是否以0xCAFEBABE開頭、主次版本號(hào)是否在當(dāng)前虛擬機(jī)的處理范圍之內(nèi)、常量池中的常量是否有不被支持的類型。
  • 元數(shù)據(jù)驗(yàn)證:對字節(jié)碼描述的信息進(jìn)行語義分析(注意:對比javac編譯階段的語義分析),以保證其描述的信息符合Java語言規(guī)范的要求;例如:這個(gè)類是否有父類,除了java.lang.Object之外。
  • 字節(jié)碼驗(yàn)證:通過數(shù)據(jù)流和控制流分析,確定程序語義是合法的、符合邏輯的。
  • 符號(hào)引用驗(yàn)證:確保解析動(dòng)作能正確執(zhí)行。

驗(yàn)證階段是非常重要的,但不是必須的,它對程序運(yùn)行期沒有影響,如果所引用的類經(jīng)過反復(fù)驗(yàn)證,那么可以考慮采用-Xverifynone參數(shù)來關(guān)閉大部分的類驗(yàn)證措施,以縮短虛擬機(jī)類加載的時(shí)間。

準(zhǔn)備(重點(diǎn))

當(dāng)完成字節(jié)碼文件的校驗(yàn)之后,JVM 便會(huì)開始為類變量分配內(nèi)存并初始化。這里需要注意兩個(gè)關(guān)鍵點(diǎn),即內(nèi)存分配的對象以及初始化的類型。

  • 內(nèi)存分配的對象。Java 中的變量有「類變量」和「類成員變量」兩種類型,「類變量」指的是被 static 修飾的變量,而其他所有類型的變量都屬于「類成員變量」。在準(zhǔn)備階段,JVM 只會(huì)為「類變量」分配內(nèi)存,而不會(huì)為「類成員變量」分配內(nèi)存。「類成員變量」的內(nèi)存分配需要等到初始化階段才開始。

例如下面的代碼在準(zhǔn)備階段,只會(huì)為 factor 屬性分配內(nèi)存,而不會(huì)為 website 屬性分配內(nèi)存。

public static int factor = 3; public String website = "www.baidu.com";
  • 初始化的類型。在準(zhǔn)備階段,JVM 會(huì)為類變量分配內(nèi)存,并為其初始化。但是這里的初始化指的是為變量賦予 Java 語言中該數(shù)據(jù)類型的零值,而不是用戶代碼里初始化的值。

例如下面的代碼在準(zhǔn)備階段之后,sector 的值將是 0,而不是 3。

public static int sector = 3;

但如果一個(gè)變量是常量(被 static final 修飾)的話,那么在準(zhǔn)備階段,屬性便會(huì)被賦予用戶希望的值。例如下面的代碼在準(zhǔn)備階段之后,number 的值將是 3,而不是 0。

public static final int number = 3;

兩個(gè)語句的區(qū)別是一個(gè)有 final 關(guān)鍵字修飾,另外一個(gè)沒有。而 final 關(guān)鍵字在 Java 中代表不可改變的意思,number 的值一旦賦值就不會(huì)在改變了。既然一旦賦值就不會(huì)再改變,那么就必須一開始就給其賦予用戶想要的值,因此被 final 修飾的類變量在準(zhǔn)備階段就會(huì)被賦予想要的值。而沒有被 final 修飾的類變量,其可能在初始化階段或者運(yùn)行階段發(fā)生變化,所以就沒有必要在準(zhǔn)備階段對它賦予用戶想要的值。

解析

解析階段是虛擬機(jī)將常量池內(nèi)的符號(hào)引用替換為直接引用的過程,解析動(dòng)作主要針對類或接口、字段、類方法、接口方法、方法類型、方法句柄和調(diào)用點(diǎn)限定符7類符號(hào)引用進(jìn)行。

  • 符號(hào)引用:簡單的理解就是字符串,比如引用一個(gè)類,java.util.ArrayList 這就是一個(gè)符號(hào)引用,字符串引用的對象不一定被加載。
  • 直接引用:指針或者地址偏移量。引用對象一定在內(nèi)存(已經(jīng)加載)。
  • 初始化

    初始化,這個(gè)階段就是執(zhí)行類構(gòu)造器< clinit >()方法的過程,為類的靜態(tài)變量賦予正確的初始值,JVM負(fù)責(zé)對類進(jìn)行初始化,主要對類變量進(jìn)行初始化。在Java中對類變量進(jìn)行初始值設(shè)定有兩種方式:

    • ①聲明類變量是指定初始值
    • ②使用靜態(tài)代碼塊為類變量指定初始值

    JVM初始化步驟

    • 1、假如這個(gè)類還沒有被加載和連接,則程序先加載并連接該類
    • 2、假如該類的直接父類還沒有被初始化,則先初始化其直接父類
    • 3、假如類中有初始化語句,則系統(tǒng)依次執(zhí)行這些初始化語句

    類初始化時(shí)機(jī):只有當(dāng)對類的主動(dòng)使用的時(shí)候才會(huì)導(dǎo)致類的初始化,類的主動(dòng)使用包括以下六種:

    • 創(chuàng)建類的實(shí)例,也就是new的方式
    • 訪問某個(gè)類或接口的靜態(tài)變量,或者對該靜態(tài)變量賦值
    • 調(diào)用類的靜態(tài)方法
    • 反射(如Class.forName(“com.shengsiyuan.Test”))
    • 初始化某個(gè)類的子類,則其父類也會(huì)被初始化
    • Java虛擬機(jī)啟動(dòng)時(shí)被標(biāo)明為啟動(dòng)類的類(Java Test),直接使用java.exe命令來運(yùn)行某個(gè)主類

    使用

    當(dāng) JVM 完成初始化階段之后,JVM 便開始從入口方法開始執(zhí)行用戶的程序代碼。

    卸載

    當(dāng)用戶程序代碼執(zhí)行完畢后,JVM 便開始銷毀創(chuàng)建的 Class 對象,最后負(fù)責(zé)運(yùn)行的 JVM 也退出內(nèi)存。

    類加載器

    顧名思義,類加載器(class loader)用來加載 Java 類到 Java 虛擬機(jī)中。JVM提供了3種類加載器:

    啟動(dòng)類加載器:Bootstrap ClassLoader,負(fù)責(zé)加載存放在JDKjrelib(JDK代表JDK的安裝目錄,下同)下,或被-Xbootclasspath參數(shù)指定的路徑中的,并且能被虛擬機(jī)識(shí)別的類庫(如rt.jar,所有的java.開頭的類均被Bootstrap ClassLoader加載)。啟動(dòng)類加載器是無法被Java程序直接引用的。擴(kuò)展類加載器:Extension ClassLoader,該加載器由sun.misc.Launcher$ExtClassLoader實(shí)現(xiàn),它負(fù)責(zé)加載JDKjrelibext目錄中,或者由java.ext.dirs系統(tǒng)變量指定的路徑中的所有類庫(如javax.開頭的類),開發(fā)者可以直接使用擴(kuò)展類加載器。應(yīng)用程序類加載器:Application ClassLoader,該類加載器由sun.misc.Launcher$AppClassLoader來實(shí)現(xiàn),它負(fù)責(zé)加載用戶類路徑(ClassPath)所指定的類,開發(fā)者可以直接使用該類加載器,如果應(yīng)用程序中沒有自定義過自己的類加載器,一般情況下這個(gè)就是程序中默認(rèn)的類加載器。

    應(yīng)用程序都是由這三種類加載器互相配合進(jìn)行加載的,如果有必要,我們還可以加入自定義的類加載器。

    雙親委派模型

    下圖中展示了類加載器直接的關(guān)系和雙親委派模型

    從圖中我們發(fā)現(xiàn)除啟動(dòng)類加載器外,每個(gè)加載器都有父的類加載器。
    雙親委派機(jī)制:如果一個(gè)類加載器在接到加載類的請求時(shí),它首先不會(huì)自己嘗試去加載這個(gè)類,而是把這個(gè)請求任務(wù)委托給父類加載器去完成,依次遞歸,如果父類加載器可以完成類加載任務(wù),就成功返回;只有父類加載器無法完成此加載任務(wù)時(shí),才自己去加載。

    從類的繼承關(guān)系來看,ExtClassLoader和AppClassLoader都是繼承URLClassLoader,都是ClassLoader的子類。而BootStrapClassLoader是有C寫的,不再java的ClassLoader子類中。
    從圖中可以看到類加載器間的父子關(guān)系不是以繼承的方式實(shí)現(xiàn)的,而是以組合關(guān)系的方式來復(fù)用父加載器的代碼。如果一個(gè)類加載器收到了類加載的請求,它首先會(huì)把這個(gè)請求委派給父加載器去完成,每一個(gè)層次的類加載器都是如此。 雙親委派模型的好處
    Java類隨著加載它的類加載器一起具備了一種帶有優(yōu)先級的層次關(guān)系。比如,Java中的Object類,它存放在rt.jar之中,無論哪一個(gè)類加載器要加載這個(gè)類,最終都是委派給處于模型最頂端的啟動(dòng)類加載器進(jìn)行加載,因此Object在各種類加載環(huán)境中都是同一個(gè)類。如果不采用雙親委派模型,那么由各個(gè)類加載器自己取加載的話,那么系統(tǒng)中會(huì)存在多種不同的Object類。

    jvm類加載相關(guān)鏈接:

    https://blog.csdn.net/javazejian/article/details/73413292

    https://www.jianshu.com/p/3cab74a189de

    https://www.fangzhipeng.com/javainterview/2019/04/15/class-loader.html

    http://www.ityouknow.com/jvm/2017/08/19/class-loading-principle.html

    https://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.html

    https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html

    總結(jié)

    以上是生活随笔為你收集整理的ftpwebrequest 无法加载或初始化请求的服务提供程序_jvm之类加载机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。