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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

类加载机制运行流程

發布時間:2024/4/13 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 类加载机制运行流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有沒有人聽過classloader的,我覺得還是比較重要,幾天會寫一個案例,你們想想我們最開始學JVM的時候,垃圾回收機制,算法,參數調優,今天講到類加載器,把類加載器的所有知識全部講完,字節碼技術在正常的開發是用不到的,但是為什么講呢,像代理技術里面,CGLIB的時候就可以把字節碼談出來,你這個人研究比較深了,CGLIB的底層原理,它是一個類庫,是做代理技術的,解碼的一個技術,類加載器,加載類的,應用在一些熱部署的地方,今天寫一個操作,實戰操作熱部署,你們可能之前是在TOMCAT里面配一下,我不需要重新發版服務器,今天實際底層的去操作一把,這樣聊的比較深的情況下,只要一討論熱部署我就知道,classloader重新加載一下字節碼,他一般是對字節碼文件做修改和新增的,類加載器是覆蓋你原有的,所以性能不一樣,很少通過字節碼實現,一般是通過classloader,加載字節碼文件 類加載器可能有很多人已經聽說過的,可能前面聽起來會比較痛苦,我們直接講代碼可能比較好理解一點,因為都是概念,好多都是概念,正常我們的一個JAVA代碼是怎么來的,JAVA代碼是怎么運行的,它是一開始要通過.java文件,然后編譯成.class文件,然后JVM執行class文件,這個是我相信你們學JAVA的時候一定學過的,編碼后會轉成虛擬機的一個指令,它會把文件加載到虛擬機的內存里面去,這個過程我們就可以成為類加載過程,為什么類加載的過程比較重要,尤其你們會發現在生產環境下面,我突然發現我的JAVA代碼有bug了,我不想重啟服務器,那怎么辦呢,我們可以通過熱部署技術,不需要通過重新發版服務器,字節碼二進制文件,你需要學C語言,需要學匯編的,我們沒有必要研究那么底層,主要是用JAVA寫代碼,其實不要把類加載器想的高大上,你們就可以這理解,就相當于JVM,執行你的class文件,從JAVA源代碼編譯后的文件進行執行,在這個類加載過程中,可能會比較麻煩,比如最基本的,加載過程,表示讀取過程,類加載的過程可能比較廣泛,字節碼文件不一定是在硬盤上的,網絡都是可以的,當讀取完之后,他就會有幾個過程,類加載主要是有幾個過程呢,簡單是三步,加載,然后鏈接,然后再是初始化,你們把這三步說完之后,加載表示讀取字節碼文件,鏈接里面有驗證,準備,解析,解析完了之后最后才會到初始化過程,我相信很多人在初學的時候,這里面怎么這么麻煩呢,大家只要知道什么呢,這個過程沒什么意思,知道他是干嘛就行了,這個時候我就大體的去說一下,首先第一步是類加載過程,就是把class字節碼文件加載到內存中去,class文件是需要源代碼編譯后,我們寫的都是源代碼,JAVA代碼,這個時候他們會把class文件讀取到內存中去后,那么他會進行一個轉換,他會把這個class文件放在一個方法區中,進行運行,我之前講過了,方法區里面主要是放靜態的,class文件的一些信息,都會放到方法區里面的,然后他會在堆里生成一個CLASS的對象,這就是我們作為方法區訪問的一個入口的時候,你們記住就行了,系統運行的時候,你去加載這樣的class文件的時候,它是二進制文件,我們外部讀取的時候也比較多,有光盤,有硬盤,記住,也有網絡讀取class文件,這都是可以的,你們下去做個案例,我怎么通過網絡,讀取字節碼文件,我們主要將后面的代碼,整個類加載的過程是怎么樣的,相當于你加載的時候,加載完了之后運行在方法區里面之后,它會在堆內存里面,比如你們有一個對象創建好了之后,new的時候,對象是存放在堆的,引用是存在棧的,這個你們一定要記住的,然后有一個封裝的數據結構,把這個類加載過程大概的說一下

類加載器 類加載的機制的層次結構 每個編寫的”.java”拓展名類文件都存儲著需要執行的程序邏輯,這些”.java”文件經過Java編譯器編譯成拓展名為”.class”的文件, ”.class”文件中保存著Java代碼經轉換后的虛擬機指令,當需要使用某個類時,虛擬機將會加載它的”.class”文件, 并創建對應的class對象,將class文件加載到虛擬機的內存,這個過程稱為類加載,這里我們需要了解一下類加載的過程,如下: Jvm執行class文件 步驟一、類加載機制 將class文件字節碼內容加載到內存中,并將這些靜態數據轉換成方法區中的運行時數據結構,在堆中生成一個代表這個類的 java.lang.Class對象,作為方法區類數據的訪問入口,這個過程需要類加載器參與。 當系統運行時,類加載器將.class文件的二進制數據從外部存儲器(如光盤,硬盤)調入內存中, CPU再從內存中讀取指令和數據進行運算,并將運算結果存入內存中。內存在該過程中充當著"二傳手"的作用, 通俗的講,如果沒有內存,類加載器從外部存儲設備調入.class文件二進制數據直接給CPU處理,而由于CPU的 處理速度遠遠大于調入數據的速度,容易造成數據的脫節,所以需要內存起緩沖作用。 類將.class文件加載至運行時的方法區后,會在堆中創建一個Java.lang.Class對象,用來封裝類位于 方法區內的數據結構,該Class對象是在加載類的過程中創建的,每個類都對應有一個Class類型的對象, Class類的構造方法是私有的,只有JVM能夠創建。因此Class對象是反射的入口,使用該對象就可以獲得 目標類所關聯的.class文件中具體的數據結構。

類加載,字節碼文件,類加載器,記載完了之后,然后他會在方法區里面去運行這個數據的,這邊我跟你說一下,這個有好多人有誤區的,首先講一下,我們之前說過的,我們再把內存結構說一下,這個時候我們假設把它叫做棧,我再copy幾份,叫做方法區,我們叫堆,其實我還是講一下,有的地方又把方法區叫做非堆,我們就把它叫做方法區,我來問一下你們,我們這里叫做方法區,現在比如說我有一個對象,一加載出來的時候,比如有一個new User()這個對象,我又讓你接受,User user = new User(),那你們說一下,這個user對象是存放在堆呢還是存放在棧呢,你們說一下,記住這是引用,這是很多人有誤區的,在這邊我說一下,這是一個誤區,以為user是存放在堆里面,記住引用肯定是存放在棧里面,它是一個局部變量要記住了,他不是全局的,不是靜態的,所以在這邊我給你說一下,首先這個方法區,我知道很多人會答錯的,確實很正常,這個肯定是存放在棧里面的,首先方法區里是class文件加載信息,new它會存放在堆里面,但是你引用它是存放在棧里面的,記住,引用是在棧里面的,方法區存放靜態數據,我現在方法區只說兩個,我現在寫一個方法,public void add(){}我在這個方法里面寫一個User user = new User(),這個時候實際上他在棧里面,user它是引用到new User()這個對象,user它是局部變量,他不是全局的,也不是靜態的,所以這個user就存放在棧里面,引用到堆里面,當你一new的時候,這new的這個對象,new的這個對象會存放在堆里面的,我們不是在說內存結構,new出來的一個User對象,相當于你局部變量去引用的時候,user是局部變量,他只要棧區的user引用到堆區的new User(),所以這是很多人的誤區,說我的user對象是不是存放在堆里面,user沒有在堆里面,因為你是引用堆里的對象,user是局部變量的,棧里面會存放基本的局部變量的信息

類加載的最終產物就是位于堆中的Class對象(注意不是目標類對象),該對象封裝了類在方法區中的數據結構,并且向用戶提供了訪問方法區數據結構的接口,即Java反射的接口。 還有一個叫做連接的過程,連接的過程我大體的說一下,他這里又三個步驟,驗證,準備,解析,你們大體的看一下,首先認證干嘛呢,確保加載的類信息符合JVM規范,沒有安全性方面的問題,正是為類變量,靜態變量分配內存并設置類初始化值的階段,將內存在方法區里面進行分配,解析就是虛擬機常量池的符號引用替換字節引用過程,就這三個步驟,你們如果想把特別底層搞熟的話,你一定要學C語言,要學匯編的,因為它這里面特別底層,所以你們現在想學的話,想研究的特別深的話,你們要學JNI技術,這個真的是這樣的,因為之前做安卓的時候,把C語言學會了,直接建立一個native方法,JAVA直接操作C語言,不用走JAVA API了,特別方便的,有的方法是通過native進行修飾的,內部語言調用外部語言,JNI就是JAVA操作C語言里面的,這個你可以不懂沒關系,你只要大概懂就行了,JNI不是JAVA后端搞的,一般你要做安卓的時候,JNI你是必須要會的,它是要和安卓底層打交道的,然后說一下初始化過程,我之前也講過的,走類的構造函數,編譯器會自動收藏類中所有類變量的賦值動作和靜態語句塊,合并在一起進行執行,是根據你的先后過程,當你初始化一個類的時候,如果父類還沒有進行初始化的時候,先觸發父類的初始化,這個只要稍微學過JAVASE的都知道這個概念是這樣的,最后大體說一下,在這里寫了一個比較簡單的例子,你們可以看看這個例子,就是寫一個靜態代碼塊,給你們演示一個例子,通過代碼可能會比較好理解,前面都是理論知識,可能確實有點繞 步驟二、連接過程 將java類的二進制代碼合并到JVM的運行狀態之中的過程 驗證:確保加載的類信息符合JVM規范,沒有安全方面的問題 準備:正式為類變量(static變量)分配內存并設置類變量初始值的階段,這些內存都將在方法區中進行分配 解析:虛擬機常量池的符號引用替換為字節引用過程 步驟三、初始化 初始化階段是執行類構造器<clinit>()方法的過程。類構造器<clinit>()方法是由編譯器自動收藏類中的 所有類變量的賦值動作和靜態語句塊(static塊)中的語句合并產生,代碼從上往下執行。 當初始化一個類的時候,如果發現其父類還沒有進行過初始化,則需要先觸發其父類的初始化 虛擬機會保、、、證一個類的<clinit>()方法在多線程環境中被正確加鎖和同步 當范圍一個Java類的靜態域時,只有真正聲名這個域的類才會被初始化

?

總結

以上是生活随笔為你收集整理的类加载机制运行流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。