當前位置:首頁 » 編程語言 » java內存載入

java內存載入

發布時間: 2022-04-28 23:14:25

⑴ 在系統啟動時,使用java怎麼將數據載入到內存數組中

我去,這個問題就有點模糊!
既然是系統啟動,那麼基本是javaWeb的范疇了; 可以有以下幾種方法
1: 使用監聽器,ServletContextListener這個監聽器就是監聽系統啟動的,然後你實現這個介面,重寫init()方法,在裡面做一些操作,也就是放進容器內一些數組數據;
2: 把數據寫進 .properties文件中,通過spring框架掃描進內存,然後用的時候讀出來

⑵ jvm 的內存中可以把一個類載入多次么

1.類載入器深入剖析Java虛擬機與程序的生命周期:當我們執行一個java程序的時候,會啟動一個JVM進程,當程序執行完之後,JVM進程就消亡了;在如下情況下JVM將結束聲明周期:System.exit(int)方法,當執行這個方法的時候,虛擬機會退出;這個方法傳入一個整形參數,這個參數是狀態嗎:如果這個整形是0的話,就是正常退出,如果不是0的話,就是異常退出;程序正常結束;程序執行過程中,遇到了異常或錯誤,而異常終止:如果我們在程序中出現了異常,而不去處理,會將異常一直拋給main函數,main函數會將異常拋給JVM,JVM如果處理不了異常,JVM就會異常退出;由於操作系統出現錯誤導致JVM進程終止:JVM所依賴的平台出現錯誤,導致JVM終止;2.類的載入,連接和初始化載入:查找並載入類的二進制數據,將class位元組碼文件載入到內存中;連接:-驗證:確保被載入的類的正確性,使用javac編譯工具生成的位元組碼文件能通過驗證,如果不是由javac編譯生成的位元組碼文件,如果自己生成的位元組碼文件不符合JVM虛擬機對位元組碼文件的要求的話,可能會出現驗證通不過的情況;比如說隨便拿一個文件,將後綴名直接修改為.class,這樣的位元組碼文件肯定不合法;-准備:為類的靜態變數分配內存,並將其初始化為默認值;-解析:把類中的符號引用轉為直接引用;初始化:為類的靜態變數賦予正確的初始值(正確的值指的是用戶賦的值);-好像這個與連接階段的准備有些重復,在連接的准備階段只是賦予初始變數,如果用戶給這個變數賦了初始值,那麼這個變數在連接的准備階段仍然會賦予初始值;-在這個階段,才會真正的將初始值賦給靜態變數;Java程序對類的使用方式有主動使用和被動使用;所有的JVM實現,必須在每個類或者介面,被java程序「首次主動使用」時才初始化他們;主動使用:創建類的實例;訪問某個類或介面的靜態變數,或者對該靜態變數賦值;調用類的靜態方法;反射:Class.forName(「類名」);初始化一個類的子類,看做對父類的主動使用;java虛擬機啟動的時候,被標明啟動類的類,即包含main方法的類,程序的入口;除了上面6種主動使用之外,其它的情況均為被動使用,其它情況都不會執行第三步初始化;3.類的載入(1)概念類的載入:指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然後再堆區創建一個java.lang.Class對象,用來封裝類在方法區內的數據結構;反射:反射就是跟句堆區的位元組碼文件,獲取方法去的數據結構;解析:Class對象是由JVM自己創建的,所有的對象都是經過Class對象創建,這個Class對象是反射的入口,通過Class對象,可以關聯到目標class位元組碼文件的內部結構;所有的類對應的Class對象都是唯一的一個,這個類是由JVM進行創建的,並且只有JVM才會創建Class對象;類載入的最終產品是位於堆區中的Class對象,Class對象封裝了類在方法區內的數據結構,並且向Java程序員提供了訪問方法區內的數據結構的介面(反射用的介面);(2)載入.class文件的方式從本地系統中直接載入:編譯好的.class位元組碼文件直接從硬碟中載入;通過網路下載.class文件:將class位元組碼文件放在網路空間中,使用URLClassLoader來載入在網路上的.class位元組碼文件,使用默認的父親委託機制載入位元組碼文件;從zip,jar等壓縮文件中載入位元組碼文件:在開發的時候,導入jar包,就是這種方式;從專有的資料庫中提取位元組碼文件;將java源文件動態編譯為位元組碼文件;(3)類載入器lJava虛擬機自帶的類載入器:-根類載入器(Bootstrap):是C++寫的,程序員無法再java代碼中獲取這個類,如果使用getClassLoader()方法獲取到的是一個null值;packagejvm;Java代碼publicclassClassLoaderTest{publicstaticvoidmain(String[]args)throwsException{//java.lang包下的類使用的是跟類載入器進行載入的Classclazz=Class.forName("java.lang.String");System.out.println(clazz.getClassLoader());//自定義的類使用的是應用類載入器(系統載入器)Classclazz2=Class.forName("jvm.C");System.out.println(clazz2.getClassLoader());}}classC{}執行結果:nullJava代碼sun.misc.Launcher$AppClassLoader@1372a1a-擴展類載入器(Extension):Java編寫;-系統類載入器(應用載入器)(System):Java編寫;用戶自定義的類載入器:-自定義的類載入器都是java.lang.ClassLoader子類;-用戶可以定製類的載入方式String類是由根類載入器進行載入的,我們可以調用Class對象的關於代理中創建對象的類載入器:創建代理對象的時候,動態創建一個類,然後使用指定的類載入器將這個類載入到內存中,然後用載入到內存中的類生成代理對象;創建代理對象的方法:newProxyInstance(ClassLoaderloader,Class[]Interfaces,InvocationHandlerh)loader是定義的代理類的類載入器,中間的介面數組是代理類的要實現的介面列表,h是指派方法調用的調用處理程序;類載入器並不需要在某個類被「首次主動使用」時再載入它:-預載入機制:JVM規范允許類載入器在預料某個類將要被使用的時就預先載入它;-報錯時機:如果在預載入的過程中遇到了位元組碼文件缺失或者存在錯誤的情況,類載入器會在程序首次主動使用(上面提到的六種情況)該類的時候報錯(LinkageError錯誤);-不報錯時機:如果這個錯誤的位元組碼文件所對應的類一直沒有被使用,那麼類載入器就不會報告錯誤,即便有錯誤也不會報錯;LinkageError:這個錯誤是Error的子類,程序不能處理這些錯誤,這些錯誤都是由虛擬機來處理,這個錯誤表示出錯的是子類,在一定程序上依賴於另一個類,在編譯了前面一個類的時候,與後面所依賴的類出現了不兼容的情況;例如:我們使用了jdk1.6在編譯一個程序,但是運行環境是jre1.5的,就會出現LinkageError錯誤;4.類的連接(1)定義類被載入之後,就進入鏈接階段;鏈接:將已讀入內存的二進制數據合並到虛擬機的運行時環境中去;鏈接顧名思義就是講類與類之間進行關聯,例如我們在類A中調用了類B,在鏈接過程中,就將A與B進行鏈接,將面向對象語言轉化為面向過程語言;(2)類的驗證類文件的結構檢查:確保類文件遵從java類文件的固定格式,開始類的描述,聲明,方法調用格式等;語義檢查:確保類本身符合java語言的語法規定,比如final類型的類沒有子類,final類型的方法沒有被覆蓋,在eclipse中這種錯誤編譯的時候不能通過,但是通過其他的方法可以生成錯誤的位元組碼文件,這里就是檢測惡意生成的位元組碼文件;位元組碼驗證:確保位元組碼流可以被JVM安全的執行,位元組碼流代表java方法(包括靜態方法和實例方法),它是由被稱作操作碼的單位元組指令組成的序列,每一個操作碼後面跟著一個或多個操作數,位元組碼驗證步驟會檢查每個操作碼是否合法,即是否有著合法的操作數;下面是指令碼組成的序列,類似於微指令:Jvm編譯指令代碼代碼//CompiledfromByteToCharCp1122.java(version1.5:49.0,superbit)publicclasssun.io.ByteToCharCp1122extendssun.io.ByteToCharSingleByte{//Fielddescriptor#17Lsun/nio/cs/ext/IBM1122;privatestaticfinalsun.nio.cs.ext.IBM1122nioCoder;//Methoddescriptor#18()Ljava/lang/String;//Stack:1,Locals:1publicjava.lang.StringgetCharacterEncoding();0ldc[1]2areturnLinenumbers:[pc:0,line:25]//Methoddescriptor#2()V//Stack:2,Locals:1publicByteToCharCp1122();0aload_0[this]1invokespecialsun.io.ByteToCharSingleByte()[25]4aload_0[this]5getstaticsun.io.ByteToCharCp1122.nioCoder:sun.nio.cs.ext.IBM1122[23]8invokevirtualsun.nio.cs.ext.IBM1122.getDecoderSingleByteMappings():java.lang.String[27]11putfieldsun.io.ByteToCharSingleByte.byteToCharTable:java.lang.String[24]14returnLinenumbers:[pc:0,line:28][pc:4,line:29][pc:14,line:30]//Methoddescriptor#2()V//Stack:2,Locals:0static{};0newsun.nio.cs.ext.IBM1122[15]3p4invokespecialsun.nio.cs.ext.IBM1122()[26]7putstaticsun.io.ByteToCharCp1122.nioCoder:sun.nio.cs.ext.IBM1122[23]10returnLinenumbers:[pc:0,line:22]}l二進制兼容性的驗證:確保相互引用的類之間協調一致的;例如在A類的a()方法中調用B類的b()方法,JVM在驗證A類的時候,會驗證B類的b()方法,加入b()方法不存在,或者版本不兼容(A,B兩類使用不同的JDK版本編譯),會拋出NoSuchMethodError錯誤;(3)准備階段在准備階段,JVM為類的靜態變數分配內存空間,並設置默認的初始值.例如下面的Sample類,在准備階段,為int類型的靜態變數分配4個位元組,並賦予初始值0;為long類型的靜態變數b,分配8個位元組,並賦予初始值0;PS:在java中基本類型變數佔用的空間是一定的,java運行在JVM上的,在C中,就要根據平台變化而變化了;publicclassSample{Java代碼privatestaticinta=1;privatestaticlongb;static{b=2;}(4)類的解析在解析階段,JVM會把類的二進制數據中的符號引用替換為直接引用,例如在A類中的a()方法引用B類中的b()方法;在A類的二進制數據中包含了一個對B類的b()方法的符號引用,這個符號引用由b()方法的全名和相關的描述符組成,在Java解析階段,就會把這個符號引用替換為指針,這個指針就是C語言中的指針了,該指針指向B類的b()方法在方法區中的內存位置,這個指針就是直接引用;5.類的初始化在初始化階段,Java虛擬機執行類的初始化操作,為類的靜態變數賦予初始值,在程序中,靜態變數初始化有兩種途徑:直接在聲明處進行初始化,例如下面的Sample中的變數a;在靜態代碼塊中進行初始化,例如下面的Sample中的變數b;Java代碼publicclassSample{privatestaticinta=1;privatestaticlongb;static{b=2;}}6.面試題介紹Java代碼publicclassPrepareOrInit{publicstaticvoidmain(String[]args){Singletonsingleton=Singleton.getInstance();System.out.println(singleton.count1);System.out.println(singleton.count2);}}classSingleton{=newSingleton();publicstaticintcount1;publicstaticintcount2=0;privateSingleton(){count1++;count2++;}(){returnsingleton;}}執行結果:10分析:這段代碼與類的鏈接中的准備階段和初始化階段有關系,准備階段是給靜態的欄位賦予默認值,初始化階段給靜態變數賦予正確的值,即用戶的值;在主函數中,調用了類的靜態方法,相當於主動使用,這里調用了類的靜態方法;之後進行連接的准備操作,給類中的靜態變數賦予初值,singleton值為null,count1與count2值為0;執行初始化操作,給類中的靜態變數賦予正確的值,給singleton變數賦予正確的值,調用構造方法,此時count1與count2執行自增操作,兩者都變成1,然後執行count1的賦予正確值操作,這里用戶沒有賦值操作,count2用戶進行了賦值為0的操作,0將原來的1覆蓋掉了,因此結果為1,0;Java代碼publicclassPrepareOrInit{publicstaticvoidmain(String[]args){Singletonsingleton=Singleton.getInstance();System.out.println(singleton.count1);System.out.println(singleton.count2);}}classSingleton{publicstaticintcount1;publicstaticintcount2=0;=newSingleton();privateSingleton(){count1++;count2++;}(){returnsingleton;}}執行結果:11在准備階段count1和count2都賦值為0,然後在初始化階段,全部賦值為1;

⑶ java中的靜態成員是否是在類載入的時候就被載入到內存中了

對,首先可以肯定的是你的說法是正確的。

類載入的過程有以下幾個過程:載入、驗證、准備、解析

在准備的過程中,靜態成員變數就會進行內存分配,而不包括實例變數,實例變數是在對象實例化隨著對象一起分配在java堆中的。但是要注意一點,比如:public static int a=1;那變數在准備階段過後的初始值是0而不是1.因為這個時候尚未執行任何的Java方法。而是賦值了一個初始值,如果是引用成員變數就會為null,其他基本類型對應的是其基本默認值。

ps:以上資料來自《深入Jvm虛擬機》

⑷ java io流是將數據全部載入在內存的流對象里才開始讀的嗎

是的,但你說的不全。讀取有倆種方式,一種是直接讀取,一種是先放在緩沖流中,再一並讀取。內存只是個中轉站,在第一種方式中,數據是先載入在內存區,然後又被馬上被讀取出去。在第二種方式中,它會有個緩沖區,其實也就是個可以重用的內存區,它是先讀取完放在緩沖區,然後一並讀取出去!

⑸ class 類 什麼 時候被 載入 java虛擬機內存

編寫的java文件經過編譯之後形成位元組碼文件,當你的程序在運行中調用到該class類的時候,通過ClassLoader進行載入。下面詳細介紹下。
class文件從載入到jvm內存中開始,到卸載出內存為止,他的整個生命周期(整個載入過程)包括:載入,驗證,准備,解析,初始化,使用和卸載。其中驗證,准備,解析三個合稱為連接。下面重點說一下載入過程。

載入過程:

1、通過一個類的全限定名來獲取定義此類的二進制位元組流

2、將位元組流所代表的靜態存儲結構轉化為方法區的運行時存儲結構

3、在java堆中生成一個代表該類的對象,作為方法區這些數據的訪問入口

驗證:

1、文件格式驗證:是否以魔數0xCAFEBABE開頭,class文件的主次版本號是否在當前jvm處理范圍之內,常量池的常量中是否有不被支持的類型,指向常量中的索引值有無不存在的常量,等

2、元數據驗證:對位元組碼描述的信息進行語義分析,保證符合java規范。如是否有父類,是否繼承了不允許繼承的類,如果不是抽象類,是否實現了所有未實現的方法。等

3、位元組碼驗證:數據流和控制流分析。主要針對類的方法體。

4、符號引用驗證:如符號引用中通過字元串描述的全限定名是否能夠找到對應的類等

准備:

該階段正式為類變數分配內存並設置初始值。內存在方法區中分配。這里說的初始值是通常情況下說的零值。

解析:

虛擬機將常量池中的符號引用替換為直接引用的過程。包括:

1、類或介面的解析

2、欄位解析

3、類方法解析

4、介面方法解析

初始化:

類初始化階段是類載入過程的最後一步,除了載入階段用戶可以通過自定義載入器參與外,其餘動作完全由虛擬機指導控制。到了初始化階段,才真正開始執行類中定義的java程序代碼(位元組碼)。在准備階段,變數已經賦過一次系統默認值,而在初始化階段,則是根據程序制定的主觀計劃去初始化類變數和其他資源,即初始化階段是執行類構造器<clinit>()方法的過程。<clinit>是在編譯java源碼時,按照靜態塊和靜態變數賦值語句的順序生成的。如果類沒有靜態塊也沒有為靜態變數賦值,就不會生成<clinit>方法,該方法只能被虛擬機調用。

⑹ java中內存有方法區,類載入時方法和靜態屬性都會隨類載入到其中 為什麼類名不能直接調用非靜態

類載入,網上有相關介紹在第一次創建一個類的對象或者第一次調用一個類的靜態屬性和方法的時候,會發生類載入類載入期間,如果發現有靜態屬性,就給對應的靜態屬性分配內存空間,並賦值這個過程完成之後,今後在調用該類的靜態屬性,虛擬機會直接尋找改屬性先前已經分配的內存空間地址,然後調用其值。同樣,修改這個類的靜態屬性也一樣說白了,靜態屬性將永遠佔用某一塊固定的內存空間,知道程序終止但是這里有點說不通,假如一個靜態的字元串,運行過程中,不斷修改這個字元串的值,那麼其內存空間就不可能固定,所以可以認為這個靜態字元串的引用是固定的

⑺ JAVA:類的位元組碼文件被載入到內存是什麼意思

程序運行前都要進入內存,Java程序也一樣,運行前裝入內存

⑻ 小白求教,java中的.class文件是在程序執行到new的時候靠載入器載入到內存的

main方法是靜態的,隨類的載入而載入,類首先開辟了內存空間,這時main也就已經存在了,在運行時java虛擬機首先找的是main方法

⑼ java普通方法和靜態方法的載入(注意是載入)時機相同嗎存儲方法耗費內存空間嗎

靜態方法放在Date數據區 可以直接調用 和STATIC 變數一樣的 在內存開始載入的時候就有空間了 普通方法是 程序運行到的時候才開始調用直接用

⑽ java中的全局變數和靜態變數是在編譯時分配內存還是在載入時分配內存

全局變數是在創建對象的時候分配內存的 創建對象過程為

  1. 分配空間。

  2. 遞歸的創建父類對象。

  3. 初始化成員變數。

  4. 調用構造方法創建一個對象。

靜態變數是在類載入的時候分配空間的,靜態變數和對象沒有關系 是在JVM第一次讀到一個類的時候載入信息的過程中分配空間的 載入過程為

1 .載入父類(如果父類已經載入過,則不在載入)。

2.初始化靜態屬性 。

3 .按順序的初始化靜態代碼塊 初始化的前提就是分配空間 。

而且靜態變數在以後的創建對象的時候不在初始化 所以一般用靜態來保存共享信息

熱點內容
安卓市場手機版從哪裡下載 發布:2025-05-15 20:17:28 瀏覽:813
幼兒速演算法 發布:2025-05-15 20:15:08 瀏覽:86
best把槍密碼多少 發布:2025-05-15 20:13:42 瀏覽:547
android安裝程序 發布:2025-05-15 20:13:20 瀏覽:558
c語言跳出死循環 發布:2025-05-15 20:06:04 瀏覽:823
a19處理器相當於安卓哪個水平 發布:2025-05-15 20:05:29 瀏覽:638
榮耀9i安卓強行關機按哪個鍵 發布:2025-05-15 20:00:32 瀏覽:750
密碼鎖寫什麼最好 發布:2025-05-15 19:05:31 瀏覽:782
5的源碼是 發布:2025-05-15 19:04:07 瀏覽:719
c語言創建的源文件 發布:2025-05-15 18:54:08 瀏覽:611