第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
注意:本文主要參考自《深入理解Java虛擬機(jī)(第二版)》
說明:查看本文之前,推薦先知道JVM內(nèi)存結(jié)構(gòu),見《第一章 JVM內(nèi)存結(jié)構(gòu)》
1、內(nèi)存回收的區(qū)域
- 堆:這是GC的主要區(qū)域
- 方法區(qū):回收兩樣?xùn)|西
- 無用的類
- 廢棄的常量
- 棧和PC寄存器是線程私有區(qū)域,不發(fā)生GC
?
2、怎樣判斷對象是否存活
垃圾回收:回收掉死亡對象所占的內(nèi)存。判斷對象是否死亡,有兩種方式:
- 引用計數(shù)法
- 原理:給對象添加一個引用計數(shù)器,每當(dāng)有一個地方引用它時,計數(shù)器值+1;引用失效時,計數(shù)器值-1
- 實際中不用,不用的兩個原因
- 每次為對象賦值時,都要進(jìn)行計數(shù)器值的增減,消耗較大
- 對于A、B相互引用這種情況處理不了(這一點是不用的主要原因)
- 可達(dá)性分析(跟蹤收集)
- 原理:從根集合(GC Roots)開始向下掃描,根集合中的節(jié)點可以到達(dá)的節(jié)點就是存活節(jié)點,根集合中的節(jié)點到達(dá)不了的節(jié)點就是將要被回收的死亡節(jié)點,如下圖中的A/B/C是存活節(jié)點,D/E是死亡節(jié)點:
-
- 根集合中的節(jié)點包括:簡單來講,就是全局性的引用(常量和靜態(tài)屬性)和棧引用(下邊第一、三)
- Java棧中的對象引用(存在于局部變量表中,注意:局部變量表中存放的是基本數(shù)據(jù)類型和對象引用)
- 這是垃圾回收最多考慮的地方,所以有時,我們也會將死亡對象稱為"沒有引用指向的對象"
- 方法區(qū)中:常量+靜態(tài)(static)變量
- 傳到本地方法中,還沒有被本地方法釋放的對象引用
- Java棧中的對象引用(存在于局部變量表中,注意:局部變量表中存放的是基本數(shù)據(jù)類型和對象引用)
- 根集合中的節(jié)點包括:簡單來講,就是全局性的引用(常量和靜態(tài)屬性)和棧引用(下邊第一、三)
?
3、3種引用類型
- 強(qiáng)引用(Strong Reference):A a = new A();//a是強(qiáng)引用
- 軟引用(Soft Reference):當(dāng)內(nèi)存不足時,釋放軟引用所引用的對象;當(dāng)內(nèi)存足夠時,就是一個普通對象(強(qiáng)引用)
- 弱引用(Weak Reference):弱引用對象只能存活到下一次垃圾回收之前,一旦發(fā)生垃圾回收,立刻被回收掉
?
4、方法區(qū)的回收
- 廢棄常量:例如,沒有任何一個引用指向常量池中的"abc"字符串,則"abc"字符串被回收
- 無用的類:滿足以下三個條件
- Java堆中不存在該類的任何實例
- 加載該類的ClassLoader被回收
- 該類的Class對象沒有在任何地方被引用
注意:
- 在實際開發(fā)中,盡量不用JSP去做前端,而是用velocity、freemarker這樣的模板引擎去做
- 與類相關(guān)常用的三個參數(shù):
- -XX:+PrintClassHistogram:輸出類統(tǒng)計狀態(tài)
- -XX:-TraceClassLoading:打印類加載信息
- -XX:-TraceClassUnloading:打印類卸載信息 View Code
?
5、垃圾回收線程
系統(tǒng)的垃圾回收是由垃圾回收線程來檢測操作的,該線程是一個后臺線程(daemon thread)。
5.1、后臺線程與我們使用的前臺線程而言,有一個特點:當(dāng)JVM中的前臺線程數(shù)量為0時,后臺線程自動消亡。可以這樣講,后臺線程依托于前臺線程而存在。
5.2、垃圾回收線程為什么要設(shè)置成為后臺線程呢?
我們想一下,當(dāng)前臺一個線程都沒有時,垃圾還會有嗎?或者說垃圾回收還有必要嗎?答案是沒有必要,所以此時垃圾回收線程也就失去了存活的意義。
所以可以這樣講,將一個線程是否設(shè)置為后臺線程,就看這條線程在沒有其他線程存在的情況下,是否還有存活的意義。
例如,在我們使用Apache mina2做RPC時,我們在消息的接收端直接開啟一個后臺線程啟動服務(wù)來接受消息發(fā)送端發(fā)來的消息事件請求就可以。試著去想,如果在整個JVM中只有當(dāng)前的這一個后臺線程了,那么這個線程還有必要存活下來嗎?當(dāng)然沒有必要,因為消息永遠(yuǎn)都不會再發(fā)送了(前臺線程都沒了)
?
轉(zhuǎn)載于:https://www.cnblogs.com/java-zhao/p/5183048.html
總結(jié)
以上是生活随笔為你收集整理的第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring集成Memcached三种方
- 下一篇: MongoDB查询用法大全