網(wǎng)站首頁 編程語言 正文
1.為什么要有垃圾回收?
例如在C語言中,通過malloc在堆(和JVM的堆不太一樣)里申請內(nèi)存之后,就得再通過free手動釋放內(nèi)存空間,或者等到程序結(jié)束才會釋放,如果忘記釋放就可能會導(dǎo)致"內(nèi)存泄漏"
內(nèi)存泄漏:內(nèi)存越用越多,可以用的空間越來越少,,空間逐漸用完,程序就會出現(xiàn)問題.
所以申請空間之后就得靠人為記得手動釋放空間,但是只要涉及到人為,就會有不靠譜的時候,所以JVM就實現(xiàn)了垃圾回收這樣的機制(garbage collection)簡稱GC.
2.垃圾回收主要回收哪個內(nèi)存區(qū)域?
棧:棧里面是放的是局部變量,它們出了自己的作用域之后就自動回收了,所以不用刻意去回收.
程序計數(shù)器:每個線程有一個,所需空間是固定的,在線程銷毀的時候跟著銷毀就行了.
方法區(qū):放的是類對象,主要的工作是"類加載",而很少涉及"類卸載",所以需要GC不必太迫切.
堆:這里放的是new出來的對象,這里是GC最主要的工作地點.new出來的對象用完之后就需要回收.
?3.JVM怎么知道誰是垃圾呢?
在垃圾回收中有兩個典型的判定方法:1.引用計數(shù) 2.可達性分析
在JVM中使用的是可達性分析
什么是可達性分析呢?
就是我們設(shè)置一些起點作為GCRoot,從這些GCRoot開始去尋找可以訪問到的對象,將他們標(biāo)記為"可達",當(dāng)這些標(biāo)記完之后,剩下的那些就是"不可達"的也就是需要回收的垃圾了.
哪些可以作為GCRoot呢?
1.局部變量表中的局部變量? (每個線程中有一個棧,每個棧中有很多棧幀,每個戰(zhàn)幀里有一個自己的局部變量表)
2.常量池中的對象
3.方法區(qū)中靜態(tài)引用類型的成員
什么是引用計數(shù)呢?
就是使用額外的計數(shù)器記錄一個對象被多少個引用指向.如果有新的引用指向這個對象,那引用計數(shù)就+1,如果有指向這個對象的引用有減少,則計數(shù)也會跟著-1.直到計數(shù)為0的時候就意味著沒人引用它,也就成了垃圾了.此時就會被回收.
但是引用計數(shù)有兩個比較大的問題:
1.對象如果不大,空間成本高
假如這個對象比較大的話就沒什么問題,假設(shè)這個對象是1000Byte,程序計數(shù)器是4Byte
那加起來也就1004Byte
但是如果這個對象很小,只有2Byte,那加上計數(shù)器(4Byte1)就是6Byte,是原來的3倍大,空間成本太高辣!
2.有循環(huán)引用的問題
?在下面的操作之后就會有循環(huán)引用的問題.
?
兩個對象現(xiàn)在相互引用了,這樣計數(shù)器既不是0,也拿不到對象了,就會一直占著內(nèi)存.我們就稱為循環(huán)引用.
4.垃圾回收的過程
?但是這種清理方法會形成"內(nèi)存碎片",內(nèi)存并不是連續(xù)的,但是以后new對象的時候要的是連續(xù)的空間,所以這樣清理出來的空間也不太能用.
解決方法使用"復(fù)制算法"也就是將標(biāo)記的對象復(fù)制到另外一片內(nèi)存上,再將原來的整片內(nèi)存清空
?這種方法有點類似順序表的刪除操作,優(yōu)點是可以有效解決"內(nèi)存碎片問題",缺點是有點耗時.
?
典型的垃圾回收器:Serial,? ?ParNew,? ?Parallel,? ?Serial Old,? ?Parallel Old,? ?CMS,? ?G1? ?
原文鏈接:https://blog.csdn.net/qq_62592809/article/details/127714582
相關(guān)推薦
- 2023-04-18 spark?dataframe全局排序id與分組后保留最大值行_python
- 2023-03-22 Golang創(chuàng)建構(gòu)造函數(shù)的方法超詳細(xì)講解_Golang
- 2023-01-28 架構(gòu)師說比起404我們更怕200錯誤_相關(guān)技巧
- 2022-07-23 .Net創(chuàng)建型設(shè)計模式之簡單工廠模式(Simple?Factory)_基礎(chǔ)應(yīng)用
- 2022-04-08 深入理解Golang的反射reflect示例_Golang
- 2022-06-24 python學(xué)習(xí)之讀取配置文件_python
- 2022-04-02 C語言冒泡排序算法代碼詳解_C 語言
- 2022-07-04 Python繪制多因子柱狀圖的實現(xiàn)示例_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支