Java詳細(xì)分析梳理垃圾回收機(jī)制
Java語(yǔ)言的垃圾回收
1.垃圾回收機(jī)制的基本概念
問(wèn):1.什么是Java垃圾回收?
答:在Java語(yǔ)言的生命周期中,Java運(yùn)行環(huán)境提供了一個(gè)系統(tǒng)的垃圾回收器線(xiàn)程,負(fù)責(zé)自動(dòng)回收那些沒(méi)有引用與之相連的對(duì)象所占用的內(nèi)存。這種清楚無(wú)用對(duì)象進(jìn)行內(nèi)存回收的過(guò)程叫做垃圾回收。
問(wèn):2.Java垃圾回收的作用是什么?
答:垃圾回收是Java語(yǔ)言提供的一種自動(dòng)內(nèi)存回收的功能,可以讓程序員減輕內(nèi)存管理的負(fù)擔(dān),同時(shí)減少了很多錯(cuò)誤的出現(xiàn)。
問(wèn):3.Java垃圾回收的方法是什么?
答: 在一個(gè)類(lèi)的實(shí)例化對(duì)象創(chuàng)建時(shí),Java虛擬機(jī)JVM會(huì)自動(dòng)給該對(duì)象分配內(nèi)存,調(diào)用該對(duì)象的構(gòu)造方法并開(kāi)始跟蹤該對(duì)象。當(dāng)該對(duì)象停止使用時(shí),JVM會(huì)通過(guò)垃圾回收器回收該對(duì)象所占的內(nèi)存。
問(wèn):4.那么,Java是如何知道一個(gè)對(duì)象沒(méi)有用的呢?
答:因?yàn)橄到y(tǒng)中的每一個(gè)對(duì)象都有一個(gè)引用計(jì)數(shù)器,如果一個(gè)對(duì)象被引用一次,引用計(jì)數(shù)器相應(yīng)的加1,減少一次引用,相應(yīng)的引用計(jì)數(shù)器減1,以此類(lèi)推,如果一個(gè)對(duì)象的引用計(jì)數(shù)器為0,則說(shuō)明這個(gè)對(duì)象該回收了。
-------------------分割線(xiàn)-------------------
實(shí)例代碼段:
Student stu = new Student("張 三",18);
Student stu2=stu;
stu=null;
stu2=new Student("李四",20);思路:


-------------------分割線(xiàn)-------------------
當(dāng)然除了引用計(jì)數(shù)法判斷對(duì)象是否存活,還有很多的算法去判斷。例如可達(dá)性算法。雖然引用計(jì)數(shù)法原理簡(jiǎn)單,判斷效率高但是同樣存在很多的缺陷。例如對(duì)象的循環(huán)引用時(shí)計(jì)數(shù)器無(wú)法判斷等。
//循環(huán)引用示例
public class Student{
String name;
Student friend;
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í)際已是無(wú)用對(duì)象,但是無(wú)法被識(shí)別。2.Java垃圾回收機(jī)制的好處
- 很好的解決了對(duì)內(nèi)存的一些操作問(wèn)題,包括追蹤,監(jiān)測(cè),釋放。
- 防止系統(tǒng)內(nèi)存被非法釋放,更加穩(wěn)定安全。
3.Java垃圾回收機(jī)制的特點(diǎn)
只有一個(gè)變量不被任何引用類(lèi)型的變量使用時(shí),它所占用的內(nèi)存才會(huì)被垃圾回收器回收。
例如:
String str1="HelloWorld!";
String str2=str1;
str1=null;
str2=new String("HelloJava");程序運(yùn)行到第三行時(shí),"Helloworld!"對(duì)象仍然被str2引用,所以不會(huì)被垃圾回收器回收。只有當(dāng)str2引用了一個(gè)新的對(duì)象時(shí),此時(shí)該對(duì)象被當(dāng)作垃圾被回收,例如以上程序運(yùn)行到第四行的時(shí)候。
不能通過(guò)程序強(qiáng)迫垃圾回收器立即執(zhí)行
在任何時(shí)候,程序員都不能通過(guò)程序強(qiáng)迫垃圾回收器立即執(zhí)行,但是程序員可以通過(guò)調(diào)用System.gc()或者Runtime.gc()方法提示垃圾回收器對(duì)垃圾進(jìn)行回收。但是這個(gè)方法只是提醒垃圾回收器對(duì)內(nèi)存進(jìn)行回收,并不一定會(huì)立即執(zhí)行,它只是一個(gè)建議并非命令。
當(dāng)垃圾回收器將要釋放無(wú)用內(nèi)存時(shí),先調(diào)用對(duì)象的finalize()方法
當(dāng)然,在Java語(yǔ)言中,垃圾的回收是由系統(tǒng)完成的,但是,有一些任務(wù)例如清理非內(nèi)存資源,這些任務(wù)也可以通過(guò)覆蓋Object類(lèi)的finalize()方法來(lái)實(shí)現(xiàn)。
形式:
protected void finalize() throws Throwable
程序可能到運(yùn)行結(jié)束都沒(méi)有執(zhí)行垃圾回收
如果一個(gè)程序只占用少量的內(nèi)存,沒(méi)有造成嚴(yán)重的內(nèi)存需求,于是垃圾回收器沒(méi)有釋放這些對(duì)象的內(nèi)存就退出了。即雖然程序員定義了finalize()方法,JVM不一定調(diào)用它,然后調(diào)用System.gc提供內(nèi)存回收的建議也不會(huì)起作用。因此很難保證使用該方法來(lái)釋放資源是安全有效的。
-------------------分割線(xiàn)-------------------
代碼示例:
//filename:GcTest.java
public class GcTest
{
public static void main(String[] args)
{
new GcTest();
// 下面兩行代碼的作用完全相同,強(qiáng)制系統(tǒng)進(jìn)行垃圾回收
// System.gc();
Runtime.getRuntime().gc();
}
public void finalize()
{
System.out.println("系統(tǒng)正在清理GcTest對(duì)象的資源...");
}
}總結(jié)
- Java的垃圾回收機(jī)制,是C++/C語(yǔ)言的一個(gè)重要的區(qū)別,既減輕了手動(dòng)釋放垃圾內(nèi)存的壓力,又解決了錯(cuò)誤釋放引起的安全問(wèn)題!
- 作為Java開(kāi)發(fā)者,一般不需要專(zhuān)門(mén)編寫(xiě)內(nèi)存回收和垃圾清理代碼,對(duì)內(nèi)存泄露和溢出的問(wèn)題,也不需要像C程序員那樣嚴(yán)格,Java垃圾回收機(jī)制根據(jù)一定的回收策略,自動(dòng)的回收內(nèi)存,永不停息的保證JVM中的內(nèi)存空間,防止出現(xiàn)內(nèi)存泄露和溢出問(wèn)題。
到此這篇關(guān)于Java詳細(xì)分析梳理垃圾回收機(jī)制的文章就介紹到這了,更多相關(guān)Java垃圾回收機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript的基本類(lèi)型值-String類(lèi)型
String類(lèi)型用于表示由零或多個(gè)16位Unicode字符組成的字符序列,即字符串。在JavaScript中沒(méi)有單個(gè)的字符型,都是字符串。這篇文章主要介紹了JavaScript的基本類(lèi)型值String類(lèi)型,需要的朋友可以參考下2017-02-02
Spring security密碼加密實(shí)現(xiàn)代碼實(shí)例
這篇文章主要介紹了Spring security密碼加密實(shí)現(xiàn)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Slf4j+logback實(shí)現(xiàn)JSON格式日志輸出方式
這篇文章主要介紹了Slf4j+logback實(shí)現(xiàn)JSON格式日志輸出方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring Boot如何實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)增刪啟停詳解
這篇文章主要給大家介紹了關(guān)于Spring Boot如何實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)增刪啟停的相關(guān)資料,文中通過(guò)示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
SpringBoot?將配置文件掛到?jar?包外面的操作方法
在 SpringBoot 中,可以將配置文件放在 jar 包外面,這樣可以方便地修改配置而不需要重新打包和部署,這篇文章主要介紹了SpringBoot?如何將配置文件掛到?jar?包外面,需要的朋友可以參考下2023-03-03
Windows環(huán)境IDEA下Ranger1.2.0源碼編譯詳細(xì)流程
本文給大家講解Windows環(huán)境IDEA下Ranger1.2.0源碼編譯過(guò)程,通過(guò)配置Tomcat,發(fā)布?security-admin-web項(xiàng)目,編譯啟動(dòng)tomcat即可完成,需要的朋友參考下2021-06-06
springboot接收別人上傳的本地視頻實(shí)例代碼
本文通過(guò)實(shí)例代碼給大家介紹了springboot接收別人上傳的本地視頻,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07
解決Java & Idea啟動(dòng)tomcat的中文亂碼問(wèn)題
這篇文章主要介紹了Java & Idea啟動(dòng)tomcat的中文亂碼問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07

