一種Java虛擬機(jī)中類庫的多線程預(yù)加載方法
【專利摘要】本發(fā)明提供了一種Java虛擬機(jī)中類庫的多線程預(yù)加載方法。首先連接類庫,生成預(yù)加載列表,預(yù)加載列表中包含虛擬機(jī)運(yùn)行時(shí)所需要預(yù)先加載的類;然后,根據(jù)線程個(gè)數(shù),將預(yù)加載列表中的類平均分配到各個(gè)線程,同時(shí)啟動(dòng)各線程,將列表中的類加載到內(nèi)存中,并對(duì)類中的靜態(tài)變量進(jìn)行初始化;最后,將預(yù)加載的類存入共享內(nèi)存資源。本發(fā)明方法篩選記錄了Java程序運(yùn)行時(shí)需要多次加載或者必須常駐內(nèi)存的類,使得預(yù)加載類庫隨著應(yīng)用程序和用戶使用習(xí)慣的改變而自動(dòng)調(diào)整,有效提高Java程序的運(yùn)行效率;同時(shí),通過多線程同步加載預(yù)加載列表中的類,有效提高Java虛擬機(jī)啟動(dòng)階段類庫本身的加載速度。
【專利說明】 一種Java虛擬機(jī)中類庫的多線程預(yù)加載方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及Java虛擬機(jī)中的類加載技術(shù),尤其是手機(jī)系統(tǒng)Java虛擬機(jī)中類的預(yù)加載方法。
【背景技術(shù)】
[0002]類加載器在虛擬機(jī)中主要負(fù)責(zé)對(duì)類文件的查詢和加載。類加載器通過對(duì)二進(jìn)制文件的解析來加載運(yùn)行過程中該類的數(shù)據(jù)結(jié)構(gòu),然后對(duì)其進(jìn)行調(diào)用,同時(shí)裝載并連接該類中所有超類和超類之間的接口。當(dāng)虛擬機(jī)需要裝載一個(gè)類時(shí),類加載器就會(huì)查找該類所對(duì)應(yīng)的字節(jié)碼文件,然后對(duì)這個(gè)字節(jié)碼文件進(jìn)行加載,提取其中所需的數(shù)據(jù)信息存儲(chǔ)到內(nèi)存中。
[0003]運(yùn)行在手機(jī)上的Java虛擬機(jī),例如Android系統(tǒng)下的Dalvik虛擬機(jī)在設(shè)備開機(jī)時(shí)就進(jìn)行預(yù)加載,預(yù)先將所有基礎(chǔ)類加載到內(nèi)存中,以此來提高Java程序的執(zhí)行效率。
[0004]但類加載器所預(yù)先加載的基礎(chǔ)類資源量很大,很可能會(huì)導(dǎo)致設(shè)備開機(jī)時(shí)預(yù)加載類的過程時(shí)間過長。
【發(fā)明內(nèi)容】
[0005]本發(fā)明針對(duì)目前類加載器預(yù)加載的基礎(chǔ)資源量大,開機(jī)過程長的問題,提出了一種Java虛擬機(jī)中類庫的多線程預(yù)加載方法。本發(fā)明方法以多線程并發(fā)的方式來完成虛擬機(jī)預(yù)加載過程,尤其是針對(duì)在手機(jī)中使用的多核處理器,采用了多運(yùn)算引擎并行運(yùn)行的方式來提高系統(tǒng)中整體的使用效率和程序的運(yùn)行速度。
[0006]本發(fā)明提供的一種Java虛擬機(jī)中類庫的多線程預(yù)加載方法,包括如下步驟:
[0007]第一步,連接類庫,生成預(yù)加載列表,所述的預(yù)加載列表中包含虛擬機(jī)運(yùn)行時(shí)所需要預(yù)先加載的類;
[0008]第二步,根據(jù)線程個(gè)數(shù),將預(yù)加載列表中的類平均分配到各個(gè)線程,然后同時(shí)啟動(dòng)各個(gè)線程,將列表中的類加載到內(nèi)存中,并對(duì)類中的靜態(tài)變量進(jìn)行初始化;
[0009]第三步,將預(yù)加載的類存入共享內(nèi)存資源。
[0010]所述的第一步中,當(dāng)過程虛擬機(jī)初始化完成后開始查詢類庫中的每個(gè)類,若類滿足如下任一條件時(shí),將類加入預(yù)加載列表,條件如下:(1)至少被兩個(gè)應(yīng)用所加載;(2)所需要加載的時(shí)間大于額定最小值;(3)常駐內(nèi)存區(qū)域。
[0011]所述的第二步中,各個(gè)線程的工作過程為:首先獲取一個(gè)輸入流,用于讀取預(yù)加載列表中類的信息;然后創(chuàng)建類相應(yīng)的存貯對(duì)象,設(shè)置緩存額度和讀取對(duì)象;對(duì)預(yù)加載列表中當(dāng)前行包含的注釋和空行忽略掉;最后調(diào)用Java虛擬機(jī)中的接口將類的信息加載到內(nèi)存中,并對(duì)類中的靜態(tài)變量進(jìn)行初始化。
[0012]本發(fā)明的優(yōu)點(diǎn)與積極效果在于:通過預(yù)加載列表的方式篩選記錄Java程序運(yùn)行時(shí)需要多次加載或者必須常駐內(nèi)存的類,從而預(yù)測出下次運(yùn)行時(shí)需要預(yù)加載的類表,可以使得預(yù)加載類庫隨著應(yīng)用程序和用戶使用習(xí)慣的改變而自動(dòng)調(diào)整,從而有效提高Java程序的運(yùn)行效率。同時(shí),通過多線程加載的方式同步加載預(yù)加載列表中的類,可以有效提高 Java虛擬機(jī)啟動(dòng)階段類庫本身的加載速度。
【專利附圖】
【附圖說明】
[0013]圖1是本發(fā)明的Java虛擬機(jī)中類庫的多線程加載方法的原理示意圖;
[0014]圖2是本發(fā)明中預(yù)加載列表的生成方法示意圖;
[0015]圖3是本發(fā)明中多線程同步預(yù)加載類的過程示意圖。
【具體實(shí)施方式】
[0016]下面將結(jié)合附圖和實(shí)施例對(duì)本發(fā)明作進(jìn)一步的詳細(xì)說明。
[0017]本發(fā)明工作原理如圖1所示。虛擬機(jī)的運(yùn)行過程將按照?qǐng)D1中所給出的流程來執(zhí)行,其預(yù)加載列表的生成方法則按照?qǐng)D2所示的流程進(jìn)行。在獲得分配好了的預(yù)加載類的列表后,可以采用圖3中給出的方法進(jìn)行加載。在圖1虛線部分,以及圖2和3中所提出來的方法和執(zhí)行機(jī)制均為本發(fā)明獨(dú)創(chuàng)。
[0018]圖1中給出了 Java虛擬機(jī)中類庫的多線程加載的主要過程。虛線范圍內(nèi)的部分為優(yōu)化過程。當(dāng)硬件已啟動(dòng)完成后,本發(fā)明的Java虛擬機(jī)中類庫的多線程預(yù)加載方法的過程如下:
[0019]第一步,連接類庫,生成預(yù)加載列表。把虛擬機(jī)運(yùn)行時(shí)所需要預(yù)先加載的類都列在同一個(gè)文件里,形成一個(gè)預(yù)加載列表,在加載過程中虛擬機(jī)先訪問預(yù)加載列表中的預(yù)加載項(xiàng),然后對(duì)預(yù)加載項(xiàng)逐一進(jìn)行加載。
[0020]第二步,進(jìn)行多線程類加載。通過平均分配的方法對(duì)預(yù)加載列表進(jìn)行線程分配,以并發(fā)的形式對(duì)虛擬機(jī)中的資源進(jìn)行同步預(yù)加載,初始化靜態(tài)變量。
[0021]第三步,將預(yù)加載的類信息存入共享內(nèi)存資源。
[0022]當(dāng)Java程序運(yùn)行時(shí),不必重新加載,從共享內(nèi)存資源中直接抽取所需的類,并執(zhí)行包含在已裝載的類或接口中的指令,經(jīng)Jit編譯器實(shí)時(shí)編譯或Java解釋器編譯,獲取字節(jié)碼指令,然后分析并執(zhí)行即可。本發(fā)明實(shí)施例中圖1中的硬件可以是手機(jī),操作系統(tǒng)為Android 系統(tǒng)。
[0023]如圖2所示為預(yù)加載列表的生成過程,包括步驟1.1?步驟1.5。
[0024]其中“開始”表示過程虛擬機(jī)已初始化完成。
[0025]步驟1.1:連接類庫,獲取類信息,依次讀取每個(gè)類開始執(zhí)行步驟1.2。
[0026]步驟1.2:判斷所讀取的類是否被至少兩個(gè)應(yīng)用所加載,如果是,將該類加入預(yù)加載列表,然后轉(zhuǎn)步驟1.5執(zhí)行;如果否,則進(jìn)入下一步判斷。
[0027]步驟1.3:判斷所讀取的類所需要加載的時(shí)間是否大于額定最小值,如果是,將該類加入預(yù)加載列表,然后轉(zhuǎn)步驟1.5執(zhí)行;如果否,則進(jìn)入下一步判斷。
[0028]步驟1.4:判斷所讀取的類是否常駐內(nèi)存區(qū)域,也就是該類存儲(chǔ)的是否為運(yùn)行環(huán)境必須的類信息,如果是,將該類加入預(yù)加載列表,然后執(zhí)行步驟1.5 ;如果否,則直接執(zhí)行步驟1.5。
[0029]步驟1.5:判斷是否類庫中所有的類都完成了查詢,如果是,則完成預(yù)加載列表的生成;如果否,繼續(xù)讀取下一個(gè)類,然后轉(zhuǎn)步驟1.2執(zhí)行。
[0030]通過如圖2所示的預(yù)加載列表的方式,篩選記錄Java程序運(yùn)行時(shí)需要多次加載或者必須常駐內(nèi)存的類,從而預(yù)測出下次運(yùn)行時(shí)需要預(yù)加載的類表,可以使得預(yù)加載類庫隨著應(yīng)用程序和用戶使用習(xí)慣的改變而自動(dòng)調(diào)整,從而有效提高Java程序的運(yùn)行效率。
[0031]如圖3所示為第二步中類庫的多線程加載方法,包括步驟2.1?步驟2.7。
[0032]步驟2.1:獲取預(yù)加載列表信息。
[0033]步驟2.2:根據(jù)多線程計(jì)算引擎的個(gè)數(shù),將預(yù)加載列表中的類進(jìn)行平均分配,形成多個(gè)子預(yù)加載列表。每個(gè)子預(yù)加載列表中包含的預(yù)加載類的個(gè)數(shù)基本相同。
[0034]步驟2.3:啟動(dòng)多線程,進(jìn)行類的預(yù)加載,每一個(gè)線程獲得一個(gè)子預(yù)加載列表地址。
[0035]步驟2.4:各個(gè)線程中,首先獲取一個(gè)輸入流,以便讀取虛擬機(jī)的預(yù)加載列表中記錄的類。
[0036]步驟2.5:在獲取輸入流的基礎(chǔ)上,創(chuàng)建類相應(yīng)的存貯對(duì)象,設(shè)置緩存(Buffer)額度、讀取(Reader)對(duì)象等,例如創(chuàng)建BufferedReader對(duì)象,并讀取預(yù)加載列表中的內(nèi)容。
[0037]步驟2.6:判斷輸入的預(yù)加載列表中當(dāng)前行是否包含注釋或是空行,如果否,進(jìn)行下一步;否則,如果包含注釋,則忽略所讀內(nèi)容中的注釋,然后執(zhí)行步驟2.7,如果是空行,則繼續(xù)讀取下一行進(jìn)行判斷。
[0038]步驟2.7:調(diào)用Java虛擬機(jī)中相應(yīng)的接口,例如Class.forName O接口,將列表中的類的信息加載到內(nèi)存中,對(duì)類中的靜態(tài)變量進(jìn)行初始化。
[0039]通過多線程加載的方式同步加載預(yù)加載列表中的類,可以有效提高Java虛擬機(jī)啟動(dòng)階段類庫本身的加載速度。
【權(quán)利要求】
1.一種Java虛擬機(jī)中類庫的多線程預(yù)加載方法,其特征在于,包括如下步驟: 步驟1:連接類庫,生成預(yù)加載列表;所述的預(yù)加載列表中包含虛擬機(jī)運(yùn)行時(shí)所需要預(yù)先加載的類;當(dāng)過程虛擬機(jī)初始化完成后,開始查詢類庫中的每個(gè)類,若類滿足如下任一條件時(shí),將類加入預(yù)加載列表,條件如下:(I)至少被兩個(gè)應(yīng)用所加載,(2)所需要加載的時(shí)間大于額定最小值,(3)常駐內(nèi)存區(qū)域; 步驟2:根據(jù)線程個(gè)數(shù),將預(yù)加載列表中的類平均分配到各個(gè)線程,然后同時(shí)啟動(dòng)各個(gè)線程,將列表中的類加載到內(nèi)存中,并對(duì)類中的靜態(tài)變量進(jìn)行初始化; 步驟3:將預(yù)加載的類存入共享內(nèi)存資源。
2.根據(jù)權(quán)利要求1所述的Java虛擬機(jī)中類庫的多線程預(yù)加載方法,其特征在于,步驟2中所述的各個(gè)線程的工作過程為:首先獲取一個(gè)輸入流,用于讀取預(yù)加載列表中類的信息;然后創(chuàng)建類相應(yīng)的存貯對(duì)象,設(shè)置緩存額度和讀取對(duì)象;對(duì)預(yù)加載列表中當(dāng)前行包含的注釋和空行忽略掉;最后調(diào)用Java虛擬機(jī)中的接口將類的信息加載到內(nèi)存中,并對(duì)類中的靜態(tài)變量進(jìn)行初始化。
【文檔編號(hào)】G06F9/445GK103793249SQ201410035171
【公開日】2014年5月14日 申請(qǐng)日期:2014年1月24日 優(yōu)先權(quán)日:2014年1月24日
【發(fā)明者】趙勝男, 史曉華, 范禮陽, 楊海燕 申請(qǐng)人:北京航空航天大學(xué)