Java內(nèi)存管理垃圾回收基礎(chǔ)詳解
Java內(nèi)存模型
在Java中,內(nèi)存被劃分為以下幾個(gè)區(qū)域:
- 堆(Heap):存儲(chǔ)對(duì)象實(shí)例和數(shù)組,是垃圾回收的主要區(qū)域。
- 棧(Stack):存儲(chǔ)局部變量和方法調(diào)用。每個(gè)線程有自己的棧。
- 方法區(qū)(Method Area):存儲(chǔ)類信息,如類的結(jié)構(gòu)、方法、字段等。
- 本地方法棧(Native Method Stack):存儲(chǔ)本地方法(如JNI)的調(diào)用。
- 程序計(jì)數(shù)器(Program Counter Register):指示當(dāng)前線程執(zhí)行的字節(jié)碼指令。
Java對(duì)象的生命周期
Java對(duì)象的生命周期分為以下幾個(gè)階段:
- 創(chuàng)建:使用
new關(guān)鍵字創(chuàng)建對(duì)象實(shí)例。 - 使用:對(duì)象被程序引用和使用。
- 不可達(dá):對(duì)象沒(méi)有任何引用指向它,無(wú)法被程序訪問(wèn)。
- 垃圾回收:垃圾回收器回收不可達(dá)對(duì)象所占用的內(nèi)存。
- 內(nèi)存釋放:內(nèi)存被釋放并歸還給系統(tǒng)。
垃圾回收
Java的垃圾回收器自動(dòng)回收不再使用的對(duì)象。垃圾回收的目的是釋放無(wú)用對(duì)象占用的內(nèi)存,避免內(nèi)存泄漏。垃圾回收過(guò)程主要發(fā)生在堆內(nèi)存區(qū)域。
垃圾回收器的工作原理:
- 標(biāo)記:垃圾回收器會(huì)找出所有不可達(dá)的對(duì)象,并將它們標(biāo)記為垃圾。
- 清除:垃圾回收器會(huì)回收被標(biāo)記的對(duì)象所占用的內(nèi)存。
Java中常用的垃圾回收算法:
- 引用計(jì)數(shù)法:每個(gè)對(duì)象維護(hù)一個(gè)引用計(jì)數(shù),當(dāng)引用計(jì)數(shù)為0時(shí),對(duì)象被視為垃圾。但這種方法無(wú)法解決循環(huán)引用問(wèn)題。
- 標(biāo)記-清除(Mark-Sweep):分為標(biāo)記和清除兩個(gè)階段,標(biāo)記階段標(biāo)記所有不可達(dá)對(duì)象,清除階段回收它們的內(nèi)存。但可能產(chǎn)生內(nèi)存碎片。
- 標(biāo)記-整理(Mark-Compact):在標(biāo)記-清除基礎(chǔ)上,將存活對(duì)象整理到內(nèi)存的一端,回收邊界以外的內(nèi)存。解決了內(nèi)存碎片問(wèn)題。
- 分代收集(Generational Collection):將堆內(nèi)存劃分為新生代和老年代,針對(duì)不同代采用不同的垃圾回收策略。新生代使用復(fù)制算法(Copying),老年代使用標(biāo)記-清除或標(biāo)記-整理算法。
內(nèi)存泄漏與內(nèi)存溢出
- 內(nèi)存泄漏:程序中某個(gè)對(duì)象不再使用,但仍然被引用,導(dǎo)致無(wú)法被垃圾回收器回收。內(nèi)存泄漏可能導(dǎo)致內(nèi)存溢出。
- 內(nèi)存溢出:程序請(qǐng)求的內(nèi)存超過(guò)了系統(tǒng)可分配的最大內(nèi)存,導(dǎo)致程序崩潰。
避免內(nèi)存泄漏的方法:
- 及時(shí)釋放不再使用的對(duì)象引用。
- 避免靜態(tài)集合類引用長(zhǎng)期占用內(nèi)存的對(duì)象。
- 使用WeakReference、SoftReference等弱引用類型。
示例
下面的示例展示了一個(gè)簡(jiǎn)單的類及其實(shí)例化過(guò)程,以及垃圾回收的觸發(fā)。
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Student student1 = new Student("Alice", 20); // 創(chuàng)建一個(gè)Student實(shí)例
Student student2 = new Student("Bob", 22); // 創(chuàng)建另一個(gè)Student實(shí)例
student1 = student2; // student1引用指向student2,此時(shí)原先的"student1"實(shí)例無(wú)法訪問(wèn),成為垃圾
System.gc(); // 建議JVM進(jìn)行垃圾回收(注意:這并不保證立即進(jìn)行垃圾回收)
}
}在這個(gè)示例中,我們創(chuàng)建了兩個(gè)Student實(shí)例。當(dāng)student1引用指向student2時(shí),原來(lái)的student1實(shí)例變得不可達(dá),成為垃圾。我們使用System.gc()建議JVM進(jìn)行垃圾回收。需要注意的是,System.gc()并不保證立即進(jìn)行垃圾回收,具體的回收時(shí)機(jī)取決于JVM的實(shí)現(xiàn)。
這一節(jié)我們?cè)敿?xì)講解了Java內(nèi)存管理與垃圾回收的相關(guān)知識(shí),包括內(nèi)存模型、對(duì)象的生命周期、垃圾回收原理及算法、內(nèi)存泄漏與內(nèi)存溢出等內(nèi)容。我們還通過(guò)一個(gè)簡(jiǎn)單的示例展示了垃圾回收的觸發(fā)。希望這些內(nèi)容對(duì)你有所幫助,更多關(guān)于Java內(nèi)存管理垃圾回收的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring?@bean和@component注解區(qū)別
本文主要介紹了Spring?@bean和@component注解區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
JavaWeb中請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求重定向的區(qū)別以及使用
今天帶大家學(xué)習(xí)JavaWeb的相關(guān)知識(shí),文章圍繞著JavaWeb中請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求重定向的區(qū)別以及使用展開,文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
java 中@Deprecated 注解的實(shí)例詳解
這篇文章主要介紹了java 中@Deprecated 注解的實(shí)例詳解的相關(guān)資料,這里對(duì)@Deprecated注解進(jìn)行了詳細(xì)介紹,希望能幫助到大家,需要的朋友可以參考下2017-08-08
rabbitmq的消息持久化處理開啟,再關(guān)閉后,消費(fèi)者啟動(dòng)報(bào)錯(cuò)問(wèn)題
這篇文章主要介紹了rabbitmq的消息持久化處理開啟,再關(guān)閉后,消費(fèi)者啟動(dòng)報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
@Configuration保證@Bean單例語(yǔ)義方法介紹
這篇文章主要介紹了SpringBoot中的@Configuration與@Bean注解,在進(jìn)行項(xiàng)目編寫前,我們還需要知道一個(gè)東西,就是SpringBoot對(duì)我們的SpringMVC還做了哪些配置,包括如何擴(kuò)展,如何定制,只有把這些都搞清楚了,我們?cè)谥笫褂貌艜?huì)更加得心應(yīng)手2023-01-01
SpringBoot+WebSocket實(shí)現(xiàn)即時(shí)通訊的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用SpringBoot+WebSocket實(shí)現(xiàn)即時(shí)通訊功能,文中示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以參考一下2022-05-05

