中文字幕欧美日韩一区二区三区_高清久久一区_阳光姐妹淘韩国版_日韩精品免费视频一区二区三区_91在线成人_一级黄色免费_精品欧美黑人一区二区三区

深入理解Java虛擬機總結

基礎了解
Java 程序的執行過程:Java 源代碼文件(.Java文件)-> Java Compiler(Java編譯器)->Java 字節碼文件(.class文件)->類加載器(Class Loader)->Runtime Data Area(運行時數據)-> Execution Engine(執行引擎)
各種基本類型:boolean、byte、char、short、int、float、long、double;
對象引用:reference類型 不等于對象本身,可能是對象的句柄也可能對象的引用指針
局部變量默認沒有初始值,不賦值是不可以使用的。和類變量(默認是有的)不一樣;
額外了解:插入式注解處理器:需要繼承AbstractProcessor;
內存管理機制
深入理解Java虛擬機總結
本地方法棧和虛擬機棧有的虛擬機是不分的;
jvm各個區域的概要
深入理解Java虛擬機總結
對象訪問定位
深入理解Java虛擬機總結
深入理解Java虛擬機總結
句柄優勢:reference本身不需要修改,只會改變句柄中的實例數據指針

直接指針訪問優勢:最大好處速度快。節省了一次指針定位的開銷;

HotSpot采用此方式

對象的布局
3個區域:對象頭(Header)、實例數據(Instance Data)和對齊填充(Padding)

header:(官方稱 Mark Word)運行時數據,入哈希碼(HashCode)、GC分代年齡 鎖狀態標識

Instance Data:類型指針,既對象只想他的類元數據的指針;

Padding:因為對象的大小必須是8字節的整數倍。如果數據沒有對齊。需要Padding來補全

垃圾收集器與內存分配策略
主要思考的問題:
標記-那些內存(那些死,那些活著)需要回收?
什么時候回收?
如何回收?

標記概要
標記算法
1)引用計數法(不能用):每當一個地方引用它時,計數器+1,引用失效時,計數器-1,任何時刻計數器為0的對象就是不可能在被使用

java沒有用 最主要的原因很難解決對象之間互相循環引用的問題;
**> public class ReferenceCountingGC {

public Object instance=null;
public static void main(String[] args) {
    ReferenceCountingGC objA=  new ReferenceCountingGC();
    ReferenceCountingGC objB=  new ReferenceCountingGC();
    objA.instance=objB;
    objB.instance=objA;
    objA=null;
    objB=null;
}

}**

2)可達性分析算法:
深入理解Java虛擬機總結
Java 語言中,可作為GC Roots的對象包括下面幾種;
虛擬機棧中(棧幀中的本地變量表)的引用對象
方法區中類靜態屬性引用對象
方法區中類常量引用對象
本地方法棧JNI引用的對象

四種引用
引用分為四種 強,軟,弱,虛四種 強度依次減弱
強引用:類似Object obj=new Object() 這類引用,只要強引用還在,垃圾收集器就永遠不會回收被引用的對象;
軟引用:用來描述一些還有用但并未必須的對象。內存溢出異常之前,會把這些對象列入回收范圍之內進行二次回收。如果回收后還沒有足夠的內存這回OOM;
弱引用:用來描述非必須的對象。若引用關聯的對象只能活到下一次垃圾回收之前;
虛引用:唯一目的對象被回收時收到一個系統通知

不可達對象的最后歷程
總結:finalize()方法不執行或者只能執行一次

不可達對象,也并非”非死不可” 這時候是在緩刑階段。要真正宣告死亡,至少要經理兩次標記過程。
如果對象進行可達性分析后發現沒有GC Roots相關聯的引用鏈,會被第一次標記并且進行一次篩選,篩選條件是此對象是否有必要執行finalize()方法。
對象沒有覆蓋finalize方法(逃脫命運的最后機會),或者finalize()方法被虛擬機掉用過(只能執行一次),虛擬機將這兩種情況都視為”沒有必要執行”
如果被判定有必要執行,那么對象會放置叫一個F-Queue的隊列之中,并且稍后虛擬機自動建立Finalize線程去執行它既finalize方法
但并不承諾會等待他運行結束,怕死循環或者運行緩慢。finalize方法是逃脫命運的最后機會,如果沒有逃脫就真的被回收了;

垃圾收集算法

標記-清除算法(基礎算法,剩下的都是基于它的不足而進行改進的)
標記:標記所有需要回收的對象

清除:統一回收所有被標記的對象

不足1:效率問題,標記和清除效率都不高;
不足2:空間問題,產生大量的不連續的內存碎片
深入理解Java虛擬機總結
深入理解Java虛擬機總結
復制(Copying)算法
內存容量劃分兩個大小相等的兩塊,每次使用其中的一塊。這塊用完了復制存活的對象到另一塊,在把這塊清理掉

不足:代價太高 把內存縮小為原來的一半;

現代的商用虛擬街都采用這種算法來回收新生代;因為新生代都是 朝生暮死 所以不需要1:1來劃分
而將內存分為一塊較大的Eden 和兩個較小的Survivor 默認大小比;8:1, 每次新生代中可用的內存空間是整個新生代容量的90=(Eden+Survivor),
“浪費” 10 因為沒辦法保證回收只有不多于10的存活,Survivor空間不夠需要老年代進行 擔保;
0深入理解Java虛擬機總結
深入理解Java虛擬機總結
標記-整理(Mark-Compact)算法(老年代常用)
標記和以前一樣,后續步驟不是直接回收,而是存活對象向一端移動,然后清理邊界以外的內存;
深入理解Java虛擬機總結
深入理解Java虛擬機總結
分代收集算法
根據對象存活周期將內存劃分不同的幾塊。一般堆分為 新生代 和老年代。這樣根據年代的特點采用最適當的收集算法

新生代:少量存活 選擇復制算法

老年代:存活率高,沒有額外空間擔保,必須使用 標記清理 或者標記整理;
GC會產生停頓(Sun也叫它 “Stop The World”),OoMap 存放著GC Roots,不是每條指令都生成一個。

不是任何時都能停下來進行 GC ,只有在 “特定的位置” 才可以GC 這個位置也叫安全點(Safepoint)

安全點的選定基本上是以程序”是否具有讓程序長時間執行的特征”為標準選定的

關于安全點另一個需要考慮的就是如何在GC發生的時讓所有線程都”跑”到最近的安全點上在停下來;有兩種方案

搶先式中斷(Preemptive Suspension)(現在幾乎都這種方案):不需要線程的執行代碼主動配合,GC發生時候先把線程全部中斷,如果有線程不在安全點,就回復線程讓它跑到安全點。

主動式中斷(Voluntary Suspension):當GC需要中斷線程的時候,不對線程造作,僅僅簡單地設置一個標志位,各個線程執行的時候主動去輪詢這個標志位,發現中斷標志位真就掛起,輪詢標志的地方安全點重合。
而對于不執行的線程,任何時間都是安全的也稱為安全區;

垃圾收集器

7種垃圾收集器的介紹
深入理解Java虛擬機總結
深入理解Java虛擬機總結
G1收集器因為沒有商用的就不寫了;

Serial:單線程收集器,在進行垃圾收集時,必須要暫停其他所有的工作線程,直到它收集結束。

需要STW(Stop The World),停頓時間長。

簡單高效,對于單個CPU環境而言,Serial收集器由于沒有線程交互開銷,可以獲取最高的單線程收集效率。

ParNew:是Serial的多線程版本,除了使用多線程進行垃圾收集外,其他行為與Serial完全一樣

Tips:1.Server模式下虛擬機的首選新生收集器,與CMS進行搭配使用。

Parallel Scavenge:目標是達到一個可控制的吞吐量,吞吐量 = 運行用戶代碼時間 / (運行用戶代碼時間 + 垃圾收集時間),高吞吐量可以高效率地利用CPU時間,盡快完成程序的運算任務,主要適合在后臺運算而不需要太多交互的任務,并且虛擬機會根據當前系統的運行情況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大的吞吐量,這種調節方式稱為GC自適應調節策略。
Serial Old:老年代的單線程收集器,使用標記 - 整理算法,
Parallel Old:老年代的多線程收集器,使用標記 - 整理算法,吞吐量優先,適合于Parallel Scavenge搭配使用

CMS(Conrrurent Mark Sweep)收集器是以獲取最短回收停頓時間為目標的收集器。使用標記 - 清除算法,收集過程分為如下四步:
初始標記,標記GCRoots能直接關聯到的對象,時間很短。
并發標記,進行GCRoots Tracing(可達性分析)過程,時間很長。
重新標記,修正并發標記期間因用戶程序繼續運作而導致標記產生變動的那一部分對象的標記記錄,時間較長。
并發清除,回收內存空間,時間很長。
其中,并發標記與并發清除兩個階段耗時最長,但是可以與用戶線程并發執行
Tips:1. 對CPU資源非常敏感,可能會導致應用程序變慢,吞吐率下降。

無法處理浮動垃圾,因為在并發清理階段用戶線程還在運行,自然就會產生新的垃圾,而在此次收集中無法收集他們,只能留到下次收集,這部分垃圾為浮動垃圾,同時,由于用戶線程并發執行,所以需要預留一部分老年代空間提供并發收集時程序運行使用。

由于采用的標記 - 清除算法,會產生大量的內存碎片,不利于大對象的分配,可能會提前觸發一次Full GC。虛擬機提供了-XX:+UseCMSCompactAtFullCollection參數來進行碎片的合并整理過程,這樣會使得停頓時間變長,虛擬機還提供了一個參數配置,-XX:+CMSFullGCsBeforeCompaction,用于設置執行多少次不壓縮的Full GC后,接著來一次帶壓縮的GC。

理解一下GC日志
1
[GC (System.gc()) [PSYoungGen: 6270K->584K(9216K)] 11390K->5712K(19456K), 0.0011969 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (System.gc())]與[Full GC (System.gc())],說明垃圾收集的停頓類型,不是區分新生代GC和老年代GC的,如果有Full,則表示此次GC發生了Stop The World。
PSYoungGen: 6270K->584K(9216K),表示,新生代:該內存區域GC前已使用容量 -> 該內存區域GC后已使用容量(該內存區域總容量)
11390K->5712K(19456K),表示,GC前Java堆已使用的容量 -> GC后Java堆已使用的容量(Java堆總容量)
0.0011969 secs,表示GC所占用的時間,單位為秒。
[Times: user=0.00 sys=0.00, real=0.00 secs],表示GC的更具體的時間,user代表用戶態消耗的CPU時間,sys代表內核態消耗的CPU時間,real代表操作從開始到結束所經過的墻鐘時間。CPU時間與墻鐘時間的區別是,墻鐘時間包括各種非運算的等待耗時,如等待磁盤IO,等待線程阻塞,CPU時間則不包含這些耗時。當系統有多CPU或者多核時,多線程操作會疊加這些CPU時間,所以讀者看到user或者sys時間超過real時間也是很正常的
深入理解Java虛擬機總結GC類型
Minor GC:指發生在新生代的垃圾收集動作,非常頻繁,速度較快。
Major GC:指發生在老年代的GC,出現Major GC,經常會伴隨一次Minor GC,同時Minor GC也會引起Major GC,一般在GC日志中統稱為GC,不頻繁。
Full GC:指發生在老年代和新生代的GC,速度很慢,需要Stop The World。
大對象直接進入老年代:大對象就是大量連續內存空間的Java對象,典型的就是很長的字符串及數組。并且內存超過虛擬機設置大對象的值;

長期存活的對象進入老年代:jvm給每個對象定義一個對象年齡計數器。如果eden出生并經過第一次Minor GC后仍然存活并且能被Survivor容納的話,將被移動到Survivor空間并將對象年齡設為1.對象在Survivor區每”熬過”一次Minor GC則年齡+1,當年齡達到一定程度(默認15歲),下一次將會被晉升老年代。

動態對象年齡判定:為了更好的適應內存狀況。如果在Survivor空間中相同年齡的所有對象大小的綜合大于Survivor的一半,那么大于等于這個年齡的將被一起帶入老年代

Tips:研究代碼對象到底怎么回收請看Page:93(深入理解JVM虛擬機第二版)
空間分配擔保
深入理解Java虛擬機總結
虛擬機參數設置;
代碼的運行參數設置為: -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

靜態分派與動態分派

靜態分派
1
Map map=new HashMap();
Map(靜態類型,外觀類型接口類型(我習慣叫)):其變化僅在使用時發生,變量本身的靜態類型不會改變,并且最終的靜態類型是在編譯期可知的。

HashMap(實際類型):其變化的結果在運行期才可確定,編譯器不編譯程序時并不知道一個對象的實際類型是什么。

所有依賴靜態類型來定位方法執行版本的分派動作稱為靜態分派。
①.靜態分派典型的應用是方法重載,
②.靜態分派發生在編譯階段,因此確定靜態分派的動作實際上不是由虛擬機來執行的
③.對于方法參數的匹配也是根據變量的靜態類型來確定,在很多情況下根據參數的類型并不能找到唯一的方法調用,這個時候的處理方式是找到一個最合適的方法。比如:

public class OverLoad { 
public static void sayHello(char arg) { 
System.out.println("hello char"); 
} 
public static void sayHello(int arg) { 
System.out.println("hello int"); 
} 
public static void sayHello(long arg) { 
System.out.println("hello long"); 
} 
public static void sayHello(Character arg) { 
System.out.println("hello Character"); 
} 
public static void sayHello(Serializable arg) { 
System.out.println("hello Serializable"); 
} 
public static void sayHello(Object arg) { 
System.out.println("hello object"); 
} 
public static void sayHello(char ...arg) { 
System.out.println("hello arg..."); 
}

public static void main(String[] args) {  
    sayHello('a');  
}  

}
從頭注解方法,結果會按順序輸出。

1、基本類型是重載按char->int->long->float->double->Character->Serializable(因為Character實現了他)順序匹配的。

2、可變參數的重載優先級是最低的。

Tips:如果出現了兩個參數分, 別為Serializable和Comparable(Character實現這兩個),編譯器無法確定自動轉型那種類型。提示類型模糊拒絕編譯;

動態分派
方法執行會找到對應的實際類型。

動態加載
NB之處 不僅僅能實現別人的接口,也能實現自己的接口這樣相當于 對象本身了,但是可以卻可以在方法執行之前或之后搞事情了

**public class DynamicProxyTest { 
interface IHello{ 
void sayHello(); 
} 
static class Hello implements IHello{ 
@Override 
public void sayHello(){ 
System.out.println("hello world"); 
} 
}

static class DynamicProxy implements InvocationHandler{  
    Object originalObj;  
    Object bind(Object originalObj){  
        this.originalObj = originalObj;  
        return Proxy.newProxyInstance(originalObj.getClass().getClassLoader(), originalObj.getClass(),  
                getInterfaces(),this);  
    }  
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        System.out.println("welcome");  
        return method.invoke(originalObj, args);  
    }  

}  

public static void main(String[] args) { 
    /* 設置此系統屬性,讓JVM生成的Proxy類寫入文件.保存路徑為:com/sun/proxy(如果不存在請生工創建) */
  System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
    IHello hello = (IHello)new DynamicProxy().bind(new Hello());  
    hello.sayHello();  
}  

}**
System.getProperties().put(“sun.misc.ProxyGenerator.saveGeneratedFiles”, “true”)->設置此系統屬性,讓JVM生成的Proxy類寫入文件.保存路徑為:com/sun/proxy(如果不存在請生工創建)

java逆向工具:為了解決把1.5中編寫的代碼放到1.4 1.3的環境部署使用的問題。比較出色的Retrotranslator

Java魔法糖

泛型與擦除
編譯后的字節碼文件中替換為原生類型,并且在相應的位置插入強制轉換;

所以泛型遇到重載,不會執行編譯;例如參數List和List編譯后的文件是一樣的所以你懂的;

public class Sugar {
//看bin目錄下的編譯文件;
public static void main(String[] args) {
//泛型 自動裝箱,自動拆箱,便利循環,變長參數;
List<Integer> list= Arrays.asList(1,2,3,4);
int sum=0;
for (int integer : list) {
sum+=integer;
}
System.out.println(sum);
}
}
編譯后文件

public class Sugar {
public Sugar() {
}
public static void main(String[] args) {
List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4)});
int sum = 0;
int integer;
for(Iterator var3 = list.iterator(); var3.hasNext(); sum += integer) {
integer = ((Integer)var3.next()).intValue();
}
System.out.println(sum);
}
}
自動裝箱陷阱

高效并發

volatile型變量的特殊規則
當定義為volatile之后具備兩種特性:
第一保證此變量對所有線程的可見性。當一個線程修改了這個值,新值對于其他線程來說立即可知;
第二:禁止指令重排序優化;

volatile和普通變量性能幾乎沒有區別,比synchronized關鍵字快;

Java線程調度
主要兩種:協同式調度和搶占式調度
協同(不用):執行時間由線程本身來控制。吧自己工作執行完后主動通知系統切換到另一個線程;

壞處:如果線程出現堵塞那么所有都堵塞了

搶占:系統分配時間,切換不由線程本身來決定

Thread.yield()可以讓出執行時間.獲取時間則沒有辦法;

額外知識 ++不是原子性,AtomicInteger CAS(原子性)來避免阻塞同步;
加Java架構師進階交流群獲取Java工程化、高性能及分布式、高性能、深入淺出。高架構。
性能調優、Spring,MyBatis,Netty源碼分析和大數據等多個知識點高級進階干貨的直播免費學習權限 

北大青鳥網上報名
北大青鳥招生簡章
中文字幕欧美日韩一区二区三区_高清久久一区_阳光姐妹淘韩国版_日韩精品免费视频一区二区三区_91在线成人_一级黄色免费_精品欧美黑人一区二区三区
欧美午夜精品久久久久久孕妇 | 免费在线欧美视频| 亚洲色欲色欲www在线观看| 国产日韩欧美不卡在线| 亚洲国产成人一区二区三区| 欧美极品xxx| 国产精品对白交换视频| 亚洲人成人一区二区在线观看| 一区二区三区精密机械公司| 亚洲国产毛片aaaaa无费看 | jlzzjlzz亚洲日本少妇| gogo大胆日本视频一区| 在线观看免费视频综合| 欧美日韩国产精品自在自线| 欧美大肚乱孕交hd孕妇| 亚洲国产精品成人久久综合一区| 亚洲欧洲一区二区三区| 丝瓜av网站精品一区二区| 国产中文一区二区三区| 99久久久精品免费观看国产蜜| 91电影在线观看| 欧美成人精品福利| 亚洲免费观看高清完整版在线观看熊| 一区二区欧美国产| 国产美女娇喘av呻吟久久| 91香蕉视频在线| 91精品国产全国免费观看| 精品1区2区在线观看| 一区二区三区欧美日| 国产一区二区主播在线| 国产69精品久久777的优势| 精品日韩欧美一区二区| 不卡一卡二卡三乱码免费网站| 久久99九九99精品| 亚洲国产中文字幕| 99久久精品国产毛片| 亚洲一区欧美一区| 国产成人午夜片在线观看高清观看| 91丨porny丨中文| 久久综合色播五月| 午夜亚洲国产au精品一区二区| 粉嫩高潮美女一区二区三区| 制服视频三区第一页精品| 国产精品女主播在线观看| 久久国产精品区| 欧美美女一区二区| 亚洲欧美日韩国产另类专区| 国产高清在线精品| 精品久久久久久综合日本欧美| 亚洲国产一二三| 色拍拍在线精品视频8848| 欧美国产精品久久| 国产成人在线观看| 精品国产第一区二区三区观看体验| 香港成人在线视频| 欧美色窝79yyyycom| 综合中文字幕亚洲| 成人晚上爱看视频| 国产三级欧美三级日产三级99| 玖玖九九国产精品| 日韩免费观看高清完整版| 日本sm残虐另类| 欧美福利视频导航| 亚洲欧美视频在线观看| 成人性生交大片免费看在线播放| 久久新电视剧免费观看| 国产一区久久久| 精品伦理精品一区| 精品亚洲成a人| 精品国精品自拍自在线| 国产一本一道久久香蕉| 国产视频亚洲色图| 91丨九色丨蝌蚪富婆spa| 一区2区3区在线看| 欧美精品视频www在线观看| 午夜av电影一区| 精品91自产拍在线观看一区| 黄色精品一二区| 国产欧美综合色| 成人av在线一区二区| 亚洲激情图片qvod| 欧美高清视频在线高清观看mv色露露十八| 亚洲一区二区在线免费观看视频| 欧美日韩另类国产亚洲欧美一级| 亚洲国产sm捆绑调教视频| 欧美日韩国产一区| 美国毛片一区二区| 欧美国产日本视频| 在线观看亚洲精品| 日韩精品国产精品| 日韩欧美一区二区三区在线| 九色porny丨国产精品| 久久中文字幕电影| 风间由美一区二区三区在线观看 | 精品毛片乱码1区2区3区| 成人激情视频网站| 亚洲成人中文在线| 日韩丝袜情趣美女图片| 懂色av一区二区夜夜嗨| 一区二区三区中文字幕电影| 日韩欧美成人一区| 91在线高清观看| 免费在线观看精品| 国产精品人妖ts系列视频| 欧美日韩dvd在线观看| 国产中文字幕精品| 亚洲午夜国产一区99re久久| 精品久久人人做人人爱| 91福利小视频| 国产精品正在播放| 午夜精品一区在线观看| 中文幕一区二区三区久久蜜桃| 91福利精品视频| 国产成人aaaa| 美日韩黄色大片| 亚洲激情图片一区| 国产嫩草影院久久久久| 在线播放91灌醉迷j高跟美女| 丁香另类激情小说| 精品一区二区成人精品| 亚洲一二三四区不卡| 国产精品视频九色porn| 欧美精品一区二区三| 欧美午夜精品一区| 99精品视频一区二区| 国产综合久久久久久鬼色| 婷婷国产v国产偷v亚洲高清| 自拍偷拍欧美精品| 欧美经典一区二区| 久久久99精品免费观看| 日韩精品专区在线影院重磅| 欧美日韩一区三区| 欧亚洲嫩模精品一区三区| 99久久久免费精品国产一区二区| 国产一二精品视频| 精品一区中文字幕| 乱一区二区av| 日韩国产欧美在线观看| 亚洲va欧美va人人爽午夜| 一区二区三区产品免费精品久久75| 亚洲国产精品v| 中文字幕av一区二区三区| 国产精品无遮挡| 欧美激情综合网| 国产精品国产三级国产普通话99| 久久人人97超碰com| 久久久久久久久久久久久久久99| 日韩美一区二区三区| 欧美成人福利视频| 久久精品在线观看| 欧美国产日韩一二三区| 国产精品久久一级| 亚洲人亚洲人成电影网站色| 综合激情成人伊人| 亚洲综合在线第一页| 首页欧美精品中文字幕| 秋霞影院一区二区| 国产在线乱码一区二区三区| 国产麻豆日韩欧美久久| www.亚洲色图.com| 91麻豆swag| 欧美另类videos死尸| 精品三级在线观看| 国产日产欧美一区二区视频| 国产精品麻豆视频| 亚洲一区二区3| 久久99精品久久久| av一区二区三区在线| 日本二三区不卡| 欧美一区日本一区韩国一区| 26uuu欧美| 亚洲欧洲制服丝袜| 日本午夜一区二区| 成人免费观看av| 欧美日韩国产综合视频在线观看| 欧美成人乱码一区二区三区| 中文字幕一区二区三区在线不卡| 亚洲444eee在线观看| 国产精品1区2区3区| 欧美日韩高清在线| 日本一区二区成人| 洋洋成人永久网站入口| 奇米色一区二区| 成人福利在线看| 欧美一区二区性放荡片| 亚洲欧洲成人精品av97| 美女一区二区久久| 99久久亚洲一区二区三区青草| 日韩午夜精品电影| 亚洲欧美另类小说视频| 国产乱国产乱300精品| 欧美色成人综合| 国产精品网曝门| 另类综合日韩欧美亚洲| 91成人网在线| 最新国产精品久久精品| 国产剧情av麻豆香蕉精品| 欧美午夜不卡在线观看免费| 欧美激情一区二区三区全黄| 奇米综合一区二区三区精品视频|