2018-09-22構(gòu)造方法、垃圾回收機(jī)制、this、static

1.構(gòu)造器使用要點(diǎn):

????1.通過(guò)new關(guān)鍵字調(diào)用!!

????2.構(gòu)造器雖然有返回值(返回該類的對(duì)象),但是不能定義返回類型?(返回值的類型肯定是本類),不能在構(gòu)造器里調(diào)用return。

????3.如果我們沒(méi)有定義構(gòu)造器,則系統(tǒng)會(huì)自動(dòng)定義一個(gè)無(wú)參的構(gòu)造函數(shù)。如果已定義則編譯器不會(huì)添加!

????4.構(gòu)造器的方法名必須和類名一致!

1.1.構(gòu)造方法的重載和普通方法一樣:

?

? ? ? 普通方法重載的條件:

? ? ??1.不同的含義:形參類型、形參個(gè)數(shù)、形參順序不同

? ? ? 2.只有返回值不同不構(gòu)成方法的重載

? ? ??如:

????????int?a(String?str){}與?void?a(String?str){}

? ? ??不構(gòu)成方法重載

? ? ??3.只有形參的名稱不同,不構(gòu)成方法的重載

? ? ??如:

????????int?a(String?str){}與int?a(String?s){}

2.垃圾回收機(jī)制:

Java引入了垃圾回收機(jī)制,令C++程序員最頭疼的內(nèi)存管理問(wèn)題迎刃而解。Java程序員可以將更多的精力放到業(yè)務(wù)邏輯上而不是內(nèi)存管理工作上,大大的提高了開(kāi)發(fā)效率。


2.1垃圾回收原理和算法:

·內(nèi)存管理

  Java的內(nèi)存管理很大程度指的就是對(duì)象的管理,其中包括對(duì)象空間的分配和釋放。

  對(duì)象空間的分配:使用new關(guān)鍵字創(chuàng)建對(duì)象即可

  對(duì)象空間的釋放:將對(duì)象賦值null即可。垃圾回收器將負(fù)責(zé)回收所有”不可達(dá)”對(duì)象的內(nèi)存空間。

·垃圾回收過(guò)程(2個(gè)要點(diǎn))

  任何一種垃圾回收算法一般要做兩件基本事情:

  1. 發(fā)現(xiàn)無(wú)用的對(duì)象

  2. 回收無(wú)用對(duì)象占用的內(nèi)存空間。

  垃圾回收機(jī)制保證可以將“無(wú)用的對(duì)象”進(jìn)行回收。無(wú)用的對(duì)象指的就是沒(méi)有任何變量引用該對(duì)象。Java的垃圾回收器通過(guò)相關(guān)算法發(fā)現(xiàn)無(wú)用對(duì)象,并進(jìn)行清除和整理。

·垃圾回收相關(guān)算法

  1. 引用計(jì)數(shù)法

  堆中每個(gè)對(duì)象都有一個(gè)引用計(jì)數(shù)。被引用一次,計(jì)數(shù)加1. 被引用變量值變?yōu)閚ull,則計(jì)數(shù)減1,直到計(jì)數(shù)為0,則表示變成無(wú)用對(duì)象。優(yōu)點(diǎn)是算法簡(jiǎn)單,缺點(diǎn)是“循環(huán)引用的無(wú)用對(duì)象”無(wú)法別識(shí)別。

【示例4-7】循環(huán)引用示例

public?class?Student?{

????String?name;

????Student?friend;//在一個(gè)對(duì)象中又引用了另一個(gè)對(duì)象


????public?static?void?main(String[]?args)?{

????????Student?s1?=?new?Student();

????????Student?s2?=?new?Student();


????????s1.friend?=?s2;

????????s2.friend?=?s1;????????

????????s1?=?null;

????????s2?=?null;

????}

}

  s1和s2互相引用對(duì)方,導(dǎo)致他們引用計(jì)數(shù)不為0,但是實(shí)際已經(jīng)無(wú)用,但無(wú)法被識(shí)別。

  2. 引用可達(dá)法(根搜索算法)

  程序把所有的引用關(guān)系看作一張圖,從一個(gè)節(jié)點(diǎn)GC ROOT開(kāi)始,尋找對(duì)應(yīng)的引用節(jié)點(diǎn),找到這個(gè)節(jié)點(diǎn)以后,繼續(xù)尋找這個(gè)節(jié)點(diǎn)的引用節(jié)點(diǎn),當(dāng)所有的引用節(jié)點(diǎn)尋找完畢之后,剩余的節(jié)點(diǎn)則被認(rèn)為是沒(méi)有被引用到的節(jié)點(diǎn),即無(wú)用的節(jié)點(diǎn)。

2.2通用的分代垃圾回收機(jī)制:

? ??????分代垃圾回收機(jī)制,是基于這樣一個(gè)事實(shí):不同的對(duì)象的生命周期是不一樣的。因此,不同生命周期的對(duì)象可以采取不同的回收算法,以便提高回收效率。我們將對(duì)象分為三種狀態(tài):年輕代、年老代、持久代。JVM將堆內(nèi)存劃分為 Eden、Survivor 和 Tenured/Old 空間。

????(上面的英文翻譯Eden:伊甸園;Survivor :幸存者;Tenured/Old:終身制/ 古老)

1. 年輕代

  所有新生成的對(duì)象首先都是放在Eden區(qū)。 年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象,對(duì)應(yīng)的是Minor GC,每次 Minor GC 會(huì)清理年輕代的內(nèi)存,算法采用效率較高的復(fù)制算法,頻繁的操作,但是會(huì)浪費(fèi)內(nèi)存空間。當(dāng)“年輕代”區(qū)域存放滿對(duì)象后,就將對(duì)象存放到年老代區(qū)域。

  2. 年老代

  在年輕代中經(jīng)歷了N(默認(rèn)15)次垃圾回收后仍然存活的對(duì)象,就會(huì)被放到年老代中。因此,可以認(rèn)為年老代中存放的都是一些生命周期較長(zhǎng)的對(duì)象。年老代對(duì)象越來(lái)越多,我們就需要啟動(dòng)Major GC和Full GC(全量回收),來(lái)一次大掃除,全面清理年輕代區(qū)域和年老代區(qū)域。

  3. 持久代(不討論)

  用于存放靜態(tài)文件,如Java類、方法等。持久代對(duì)垃圾回收沒(méi)有顯著影響。

.垃圾回收過(guò)程:

1、新創(chuàng)建的對(duì)象,絕大多數(shù)都會(huì)存儲(chǔ)在Eden中,

? ? 2、當(dāng)Eden滿了(達(dá)到一定比例)不能創(chuàng)建新對(duì)象,則觸發(fā)垃圾回收(GC),將無(wú)用對(duì)象清理掉,【觸發(fā)gc就是上一段的一些垃圾回收的算法:引用可達(dá)法、引用可達(dá)法】

???????????然后剩余對(duì)象復(fù)制到某個(gè)Survivor中,如S1,同時(shí)清空Eden區(qū)

? ? 3、當(dāng)Eden區(qū)再次滿了,會(huì)將S1中的不能清空的對(duì)象存到另外一個(gè)Survivor中,如S2,

? ? ? ? ??同時(shí)將Eden區(qū)中的不能清空的對(duì)象,也復(fù)制到S1中,保證Eden和S1,均被清空。

4、重復(fù)多次(默認(rèn)15次)Survivor中沒(méi)有被清理的對(duì)象,則會(huì)復(fù)制到老年代Old(Tenured)區(qū)中,

? ? 5、當(dāng)Old區(qū)滿了,則會(huì)觸發(fā)一個(gè)一次完整地垃圾回收(FullGC),之前新生代的垃圾回收稱為(minorGC)


·Minor GC:

用于清理年輕代區(qū)域。Eden區(qū)滿了就會(huì)觸發(fā)一次Minor GC。清理無(wú)用對(duì)象,將有用對(duì)象復(fù)制到“Survivor1”、“Survivor2”區(qū)中(這兩個(gè)區(qū),大小空間也相同,同一時(shí)刻Survivor1和Survivor2只有一個(gè)在用,一個(gè)為空)

  ·Major GC:

  用于清理老年代區(qū)域。

  ·Full GC:

  用于清理年輕代、年老代區(qū)域。 成本較高,會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響。

2.3 JVM調(diào)優(yōu)和Full GC

.在對(duì)JVM調(diào)優(yōu)的過(guò)程中,很大一部分工作就是對(duì)于Full GC的調(diào)節(jié)。有如下原因可能導(dǎo)致Full GC:

  1.年老代(Tenured)被寫(xiě)滿

  2.持久代(Perm)被寫(xiě)滿

  3.System.gc()被顯式調(diào)用(程序建議GC啟動(dòng),不是調(diào)用GC)

  4.上一次GC之后Heap的各域分配策略動(dòng)態(tài)變化

3.this

· 對(duì)象創(chuàng)建的過(guò)程和this的本質(zhì)

  構(gòu)造方法是創(chuàng)建Java對(duì)象的重要途徑,通過(guò)new關(guān)鍵字調(diào)用構(gòu)造器時(shí),構(gòu)造器也確實(shí)返回該類的對(duì)象,但這個(gè)對(duì)象并不是完全由構(gòu)造器負(fù)責(zé)創(chuàng)建。創(chuàng)建一個(gè)對(duì)象分為如下四步:

  1. 分配對(duì)象空間,并將對(duì)象成員變量初始化為0或空

  2. 執(zhí)行屬性值的顯式初始化

  3. 執(zhí)行構(gòu)造方法

  4. 返回對(duì)象的地址給相關(guān)的變量

this最常的用法:

  1. ?在程序中產(chǎn)生二義性之處,應(yīng)使用this來(lái)指明當(dāng)前對(duì)象;普通方法中,this總是指向調(diào)用該方法的對(duì)象。構(gòu)造方法中,this總是指向正要初始化的對(duì)象。

  2. 使用this關(guān)鍵字調(diào)用重載的構(gòu)造方法,避免相同的初始化代碼。但只能在構(gòu)造方法中用,并且必須位于構(gòu)造方法的第一句。

  3. this不能用于static方法中。

?TestThis(int?a,?int?b){

? ? this.a=a;

? ? this.b=b;

}

TestThis(int?a,?int?b,?int?c)?{

????????this(a,?b);?//?調(diào)用帶參的構(gòu)造方法,并且必須位于第一行!

????????this.c?=?c;

????}


this的本質(zhì)就是“創(chuàng)建好的對(duì)象的地址”! 由于在構(gòu)造方法調(diào)用前,對(duì)象已經(jīng)創(chuàng)建。因此,在構(gòu)造方法中也可以使用this代表“當(dāng)前對(duì)象”?

4.static 關(guān)鍵字

在類中,用static聲明的成員變量為靜態(tài)成員變量,也稱為類變量。 類變量的生命周期和類相同,在整個(gè)應(yīng)用程序執(zhí)行期間都有效。它有如下特點(diǎn):

  1. 為該類的公用變量,屬于類,被該類的所有實(shí)例共享,在類被載入時(shí)被顯式初始化。

  2. 對(duì)于該類的所有對(duì)象來(lái)說(shuō),static成員變量只有一份。被該類的所有對(duì)象共享!!

  3. 一般用“類名.類屬性/方法”來(lái)調(diào)用。(也可以通過(guò)對(duì)象引用或類名(不需要實(shí)例化)訪問(wèn)靜態(tài)成員。)

  4. 在static方法中不可直接訪問(wèn)非static的成員。

核心要點(diǎn):

?? ??????static修飾的成員變量和方法,從屬于類。

? ? ? ? ?普通變量和方法從屬于對(duì)象的。

public?class?User2?{

????int?id;?//?id

????String?name;?//?賬戶名

????String?pwd;?//?密碼

? ?static?String?company?=?"北京尚學(xué)堂";?//?公司名稱

????public?User2(int?id,?String?name)?{

????????this.id?=?id;

????????this.name?=?name;

????}

????public?void?login()?{

????????printCompany();//非靜態(tài)可以調(diào)用靜態(tài)的(因?yàn)轭愋畔⑹窍燃虞d的java User2 就會(huì)去加載類信息,而沒(méi)new的時(shí)候是不會(huì)去創(chuàng)建對(duì)象的,所以靜態(tài)方法里不能調(diào)用非靜態(tài)信息。?)

????????System.out.println(company);?

????????System.out.println("登錄:"?+?name);

????}


????public?static?void?printCompany()?{

//?????????login();//調(diào)用非靜態(tài)成員,編譯就會(huì)報(bào)錯(cuò)

????????System.out.println(company);

????}


????public?static?void?main(String[]?args)?{

????????User2?u?=?new?User2(101,?"高小七");

????????User2.printCompany();

????????User2.company?=?"北京阿里爺爺";

????????User2.printCompany();

????}

}

下面內(nèi)存圖片解釋為什么在靜態(tài)方法中不能調(diào)用非靜態(tài)方法:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容