成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java基礎小記

ruicbAndroid / 393人閱讀

摘要:看到的只是,而由泛型附加的類型信息對來說是不可見的。然后再加載執(zhí)行類的靜態(tài)變量以及靜態(tài)語句塊。接口中基本數據類型為而抽類象不是的。本地方法接口主要是調用或實現(xiàn)的本地方法及返回結果。用戶自定義類加載器,在程序運行期間,通過的子類動態(tài)加載。

編譯機制
  編譯主要是把?.Java文件轉換為 .class 文件。其中轉換后的 .class 文件就包含了元數據,方法信息等一些信息。比如說元數據就包含了?Java 文件中聲明的常量,也就是我們所說的常量池。

泛型實現(xiàn)原理
  Java泛型實現(xiàn)原理:類型擦除
  Java的泛型是偽泛型。在編譯期間,所有的泛型信息都會被擦除掉。正確理解泛型概念的首要前提是理解類型擦出(type erasure)。
?   Java中的泛型基本上都是在編譯器這個層次來實現(xiàn)的。  
  在生成的Java字節(jié)碼中是不包含泛型中的類型信息的。使用泛型的時候加上的類型參數,會在編譯器在編譯的時候去掉。這個過程就稱為類型擦除。
  如在代碼中定義的List和List等類型,在編譯后都會變成List。JVM看到的只是List,而由泛型附加的類型信息對JVM來說是不可見的。Java編譯器會在編譯時盡可能的發(fā)現(xiàn)可能出錯的地方,但是仍然無法避免在運行時刻出現(xiàn)類型轉換異常的情況。

編譯時期和運行時期類型檢查
  Java中的許多對象(一般都是具有父子類關系的父類對象)在運行時都會出現(xiàn)兩種類型:編譯時類型和運行時類型,例如:Person person = new Student();這行代碼將會生成一個person變量,該變量的編譯時類型是Person,運行時類型是Student。
  Java的引用變量有兩個類型,一個是編譯時類型,一個是運行時類型,編譯時類型由聲明該變量時使用的類型決定,運行時類型由實際賦給該變量的對象決定。

多態(tài)實現(xiàn)原理
  基于繼承實現(xiàn)的多態(tài)可以總結如下:對于引用子類的父類類型,在處理該引用時,它適用于繼承該父類的所有子類,子類對象的不同,對方法的實現(xiàn)也就不同,執(zhí)行相同動作產生的行為也就不同。
  繼承是通過重寫父類的同一方法的幾個不同子類來體現(xiàn)的,那么就可以是通過實現(xiàn)接口并覆蓋接口中同一方法的幾不同的類體現(xiàn)的。
?  在接口的多態(tài)中,指向接口的引用必須是指定這實現(xiàn)了該接口的一個類的實例程序,在運行時,根據對象引用的實際類型來執(zhí)行對應的方法。
  當超類對象引用變量引用子類對象時,被引用對象的類型而不是引用變量的類型決定了調用誰的成員方法,但是這個被調用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法,但是它仍然要根據繼承鏈中方法調用的優(yōu)先級來確認方法,該優(yōu)先級為:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

A繼承B,加載順序

要加載類A,則先加載執(zhí)行其父類B(Object)的靜態(tài)變量以及靜態(tài)語句塊(執(zhí)行先后順序按排列的先后順序)

然后再加載執(zhí)行類A的靜態(tài)變量以及靜態(tài)語句塊。(并且1、2步驟只會執(zhí)行1次)

若需實例化類A,則先調用其父類B的構造函數,并且在調用其父類B的構造函數前,依次先調用父類B中的非靜態(tài)變量及非靜態(tài)語句塊.最后再調用父類B中的構造函數初始化

然后再依次調用類A中的非靜態(tài)變量及非靜態(tài)語句塊.最后調用A中的構造函數初始化。( 并且3、4步驟可以重復執(zhí)行)

而對于靜態(tài)方法和非靜態(tài)方法都是被動調用,即系統(tǒng)不會自動調用執(zhí)行,所以用戶沒有調用時都不執(zhí)行,主要區(qū)別在于靜態(tài)方法可以直接用類名直接調用(實例化對象也可以),而非靜態(tài)方法只能先實例化對象后才能調用。

serizeble有什么用
  序列化就是把一個對象保存到一個文件或數據庫字段中去,反序列化就是在適當的時候把這個文件再轉化成原來的對象使用。我想最主要的作用有:

在進程下次啟動時讀取上次保存的對象的信息

在不同的AppDomain或進程之間傳遞數據

在分布式應用系統(tǒng)中傳遞數據

序列化

當一個父類實現(xiàn)序列化,子類自動實現(xiàn)序列化,不需要顯式實現(xiàn)Serializable接口;

當一個對象的實例變量引用其他對象,序列化該對象時也把引用對象進行序列化;

static,transient后的變量不能被序列化;

抽象類和接口區(qū)別:

接口是抽象類的變體,接口中所有的方法都是抽象的。而抽象類是聲明方法的存在而不去實現(xiàn)它的類。

接口可以多繼承,抽象類不行

接口定義方法,不能實現(xiàn),而抽象類可以實現(xiàn)部分方法。

接口中基本數據類型為static 而抽類象不是的。

JVM虛擬機結構
JVM主要包括四個部分:

類加載器(ClassLoader):在JVM啟動時或者在類運行時將需要的class加載到JVM中。

執(zhí)行引擎:負責執(zhí)行class文件中包含的字節(jié)碼指令(執(zhí)行引擎的工作機制,這里也不細說了,這里主要介紹JVM結構);

內存區(qū)(也叫運行時數據區(qū)):是在JVM運行的時候操作所分配的內存區(qū)。運行時內存區(qū)主要可以劃分為5個區(qū)域

方法區(qū)(Method Area):用于存儲類結構信息的地方,包括常量池、靜態(tài)變量、構造函數等(JDK7 永久代,JDK metaspace)。雖然JVM規(guī)范把方法區(qū)描述為堆的一個邏輯部分,但它卻有個別名non-heap(非堆),所以大家不要搞混淆了。方法區(qū)還包含一個運行時常量池。這部分區(qū)域不是線程所私有,而是各個線程所共享的。

java堆(Heap):存儲java實例或者對象(對象和數組等實例)的地方。這塊是GC的主要區(qū)域(后面解釋)。從存儲的內容我們可以很容易知道,方法區(qū)和堆是被所有java線程共享的。

java棧(Stack):java??偸呛途€程關聯(lián)在一起,每當創(chuàng)建一個線程時,JVM就會為這個線程創(chuàng)建一個對應的java棧。在這個java棧中又會包含多個棧幀,每運行一個方法就創(chuàng)建一個棧幀,用于存儲局部變量表、操作棧、方法返回值等。每一個方法從調用直至執(zhí)行完成的過程,就對應一個棧幀在java棧中入棧到出棧的過程。所以java棧是線程私有的。

程序計數器(PC Register):用于保存當前線程執(zhí)行的內存地址。由于JVM程序是多線程執(zhí)行的(線程輪流切換),所以為了保證線程切換回來后,還能恢復到原先狀態(tài),就需要一個獨立的計數器,記錄之前中斷的地方,可見程序計數器也是線程私有的。

本地方法棧(Native Method Stack):和java棧的作用差不多,只不過是為JVM使用到的native方法服務的。

4. 本地方法接口:主要是調用C或C++實現(xiàn)的本地方法及返回結果。

雙親委派模型
  工作過程是:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,?每一個層次的類加載都是如此?,因此所有的加載請求最終都應該傳送到頂層的啟動類加載器中,只有當父加載器反饋自己無法加載這個加載請求的時候,子加載器才會嘗試自己去加載。
  使用這種機制,可以避免重復加載,當父親已經加載了該類的時候,就沒有必要子ClassLoader再加載一次(試想如果有人編寫了一個惡意的基礎類,比如String類,并裝載到JVM中將會引起多么可怕的后果呢。但是,由于有了全盤負責委托機制,String類 永遠是有根裝載器裝載,這樣就避免了事件的發(fā)生)。
  ClassLoader主要對類的請求提供服務,當JVM需要某類時,它根據名稱向ClassLoader要求這個類,然后由ClassLoader返回這個類的class對象。
  每當?JVM 啟動的時候,就會產生 三個 ClassLoader,它們分別是Bootstrap Loader, ExtClassLoader 和 AppClassLoader,ClassLoader就是用來動態(tài)加載class文件到內存當中用的。

Bootstrap Classloader啟動類加載器,主要負責java_home/lib下的核心api或者-Xbootstrap選項指定的jar包裝入工作。

Extension ClassLoader擴展類加載器,主要負責java_home/lib/ext下jar包。

App?CLassLoader 系統(tǒng)類加載器,主要負責Java -classpath/所指的目錄下的類與jar包的裝入工作。

UserCustom ClassLoader用戶自定義類加載器,在程序運行期間,通過Java.lang.Classloader的子類動態(tài)加載class。

ExtClassLoader的父類加載器是null,只不過在默認的ClassLoader 的 loadClass 方法中,當parent為null時,是交給BootStrapClassLoader來處理的,而且ExtClassLoader 沒有重寫默認的loadClass方法,所以,ExtClassLoader也會調用BootStrapLoader類加載器來加載,這就導致“BootStrapClassLoader具備了ExtClassLoader父類加載器的功能”。
查看classloader的源碼可以發(fā)現(xiàn)三個重要的方法:

loadClass。classloader加載類的入口,此方法負責加載指定名字的類,ClassLoader的實現(xiàn)方法為先從已經加載的類中尋找,如沒有則繼續(xù)從父ClassLoader中尋找,如仍然沒找到,則從BootstrapClassLoader中尋找,最后再調用findClass方法來尋找,如要改變類的加載順序,則可覆蓋此方法,如加載順序相同,則可通過覆蓋findClass來做特殊的處理,例如解密、固定路徑尋找等,當通過整個尋找類的過程仍然未獲取到Class對象時,則拋出ClassNotFoundException。如類需要resolve,則調用resolveClass進行鏈接。

findClass。它接受要加載的類作為它的參數,在該方法中會找到class文件并且讀取文件中的內容到一個 byte 數組。此方法直接拋出ClassNotFoundException,因此需要通過覆蓋loadClass或此方法來以自定義的方式加載相應的類。

defineClass。此方法負責將二進制的字節(jié)碼轉換為Class對象,這個方法對于自定義加載類而言非常重要,如二進制的字節(jié)碼的格式不符合JVM Class文件的格式,拋出ClassFormatError;如需要生成的類名和二進制字節(jié)碼中的不同,則拋出NoClassDefFoundError;如需要加載的class是受保護的、采用不同簽名的或類名是以java.開頭的,則拋出SecurityException;如需加載的class在此ClassLoader中已加載,則拋出LinkageError。

導致Gc的情況:

tenured被寫滿

perm被寫滿

System.gc()的顯式調用。

上一次GC之后heap的各域分配策略動態(tài)變化。

JVM分別對新生代和舊生代采用不同的垃圾回收機制
  將對象按其生命周期的不同劃分成:年輕代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)
  常見檢測出垃圾算法:
    引用計數法
    可達性分析算法
  新生代的GC(Minor GC): 指發(fā)生在新生代的垃圾收集動作,因為?Java 對象大多都具備朝生夕滅的特性,所以 Minor GC 非常頻繁,一般回收速度也比較快。新生代通常存活時間較短,因此基于Copying算法來進行回收,所謂Copying算法就是掃描出存活的對象,并復制到一塊新的完全未使用的空間中,對應于新生代,就是在Eden和FromSpace或ToSpace之間copy。
  新生代采用空閑指針的方式來控制GC觸發(fā),指針保持最后一個分配的對象在新生代區(qū)間的位置,當有新的對象要分配內存時,用于檢查空間是否足夠,不夠就觸發(fā)GC。當連續(xù)分配對象時,對象會逐漸從eden到survivor,最后到舊生代。
  舊生代的GC(Major GC ?/ Full GC):指發(fā)生在老年代的?GC。舊生代與新生代不同,對象存活的時間比較長,比較穩(wěn)定,因此采用標記(Mark)算法來進行回收,所謂標記就是掃描出存活的對象,然后再進行回收未被標記的對象,回收后對用空出的空間要么進行合并,要么標記出來便于下次進行分配,總之就是要減少內存碎片帶來的效率損耗。?MajorGC 的速度一般會比 Minor GC 慢 10倍以上。Thinking in java給Java?gc取了一個羅嗦的稱呼:“自適應、分代的、停止-復制、標記-掃描”式的垃圾回收器。

JVM調優(yōu)
從以下幾個方面進行:
  線程池:解決用戶響應時間長的問題
  連接池
  JVM啟動參數:調整各代的內存比例和垃圾回收算法,提高吞吐量
  程序算法:改進程序邏輯算法提高性能

內存泄露:
  概括地說,這就是內存托管語言中的內存泄漏產生的主要原因:保留下來卻永遠不再使用的對象引用。

全局集合

緩存

典型的算法是:

檢查結果是否在緩存中,如果在,就返回結果。

如果結果不在緩存中,就進行計算。

將計算出來的結果添加到緩存中,以便以后對該操作的調用可以使用。

該算法的問題(或者說是潛在的內存泄漏)出在最后一步。如果調用該操作時有相當多的不同輸入,就將有相當多的結果存儲在緩存中。很明顯這不是正確的方法。為了預防這種具有潛在破壞性的設計,程序必須確保對于緩存所使用的內存容量有一個上限。

因此,更好的算法是:

檢查結果是否在緩存中,如果在,就返回結果。

如果結果不在緩存中,就進行計算。

如果緩存所占的空間過大,就移除緩存最久的結果。

將計算出來的結果添加到緩存中,以便以后對該操作的調用可以使用

ClassLoader
  ClassLoader的特別之處在于它不僅涉及“常規(guī)”的對象引用,還涉及元對象引用,比如:字段、方法和類。這意味著只要有對字段、方法、類或ClassLoader的對象的引用,ClassLoader就會駐留在JVM中。因為ClassLoader本身可以關聯(lián)許多類及其靜態(tài)字段,所以就有許多內存被泄漏了。

volatile關鍵字怎么實現(xiàn)
  可見性的意思是當一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值。
  如果大家有興趣查看代碼JIT生成后的匯編指令,會發(fā)現(xiàn)針對volatile的變量的寫操作,會有一個Lock指令,這是用來實現(xiàn)內存屏障的,保證如果一個處理器修改了變量值,會直接將值寫回到內存,其他的處理器對應的緩存也會失效,需要重新從內存中讀取,這樣就保證所有的處理器讀到的值,都是最近的變量值。將當前處理器緩存行的數據會寫回到系統(tǒng)內存。這個寫回內存的操作會引起在其他CPU里緩存了該內存地址的數據無效。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/70067.html

相關文章

  • Java反射學習小記

    摘要:反射使用類對象提供的基本元數據,能從類對象中找出方法或字段的名稱,然后獲取表示方法或字段的對象。常見的反射手段有反射和反射。以之前的反射為例其中指定了方法的返回類型,其實不止如此。 Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類 在運行時構造任意一個類的對象 在運行時判斷任意一個類所具有的成員變量和方法 在運行時調用任意一個對象的方法 生成動態(tài)代理 很多框架...

    frank_fun 評論0 收藏0
  • Java抽象類和接口小記

    摘要:抽象類和接口小記抽象類和接口實現(xiàn)了的多態(tài)多態(tài)是面向對象程序語言的核心在項目開發(fā)過程中其實很少使用抽象類接口用得比較多今天小記一下抽象類和接口的區(qū)別抽象類抽象類不能被實例化抽象類可以繼承可以定義變量可以定義構造方法抽象方法的要顯式的寫出來其子 Java抽象類和接口小記 Java抽象類和接口實現(xiàn)了java的多態(tài).多態(tài)是面向對象程序語言的核心,在項目開發(fā)過程中,其實很少使用抽象類,接口用得比...

    Gemini 評論0 收藏0
  • JavaScript使用小記

    摘要:簡單地說程序就是數據和方法計算機能做的就是計算這個數據可以是字符串各種類型的數值整數小數等類內的屬性根本上是還是的基本數據類型布爾類型的東東為了更加快速地寫出代碼現(xiàn)在的語言都是高層次的抽象即所謂的高級編程語言了高級編程語言中的一些特性如訪問 簡單地說, 程序就是數據和方法, 計算機能做的就是計算, 這個數據可以是: 1.字符串, 2.各種類型的數值(整數, 小數等), 3.Java類內...

    stefan 評論0 收藏0
  • 【源起Netty 前傳】Linux網絡模型小記

    摘要:非阻塞模型這種也很好理解,由阻塞的死等系統(tǒng)響應進化成多次調用查看數據就緒狀態(tài)。復用模型,以及它的增強版就屬于該種模型。此時用戶進程阻塞在事件上,數據就緒系統(tǒng)予以通知。信號驅動模型應用進程建立信號處理程序時,是非阻塞的。 引言 之前的兩篇文章 FastThreadLocal怎么Fast?、ScheduledThreadPoolExecutor源碼解讀 搞的我心力交瘁,且讀源碼過程中深感功...

    Null 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<