日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

JVM中的垃圾回收

作者:忄烰燴 更新時間: 2022-11-14 編程語言

1.為什么要有垃圾回收?

例如在C語言中,通過malloc在堆(和JVM的堆不太一樣)里申請內存之后,就得再通過free手動釋放內存空間,或者等到程序結束才會釋放,如果忘記釋放就可能會導致"內存泄漏"

內存泄漏:內存越用越多,可以用的空間越來越少,,空間逐漸用完,程序就會出現問題.

所以申請空間之后就得靠人為記得手動釋放空間,但是只要涉及到人為,就會有不靠譜的時候,所以JVM就實現了垃圾回收這樣的機制(garbage collection)簡稱GC.

2.垃圾回收主要回收哪個內存區域?

棧:棧里面是放的是局部變量,它們出了自己的作用域之后就自動回收了,所以不用刻意去回收.

程序計數器:每個線程有一個,所需空間是固定的,在線程銷毀的時候跟著銷毀就行了.

方法區:放的是類對象,主要的工作是"類加載",而很少涉及"類卸載",所以需要GC不必太迫切.

堆:這里放的是new出來的對象,這里是GC最主要的工作地點.new出來的對象用完之后就需要回收.

?3.JVM怎么知道誰是垃圾呢?

在垃圾回收中有兩個典型的判定方法:1.引用計數 2.可達性分析

在JVM中使用的是可達性分析

什么是可達性分析呢?

就是我們設置一些起點作為GCRoot,從這些GCRoot開始去尋找可以訪問到的對象,將他們標記為"可達",當這些標記完之后,剩下的那些就是"不可達"的也就是需要回收的垃圾了.

哪些可以作為GCRoot呢?

1.局部變量表中的局部變量? (每個線程中有一個棧,每個棧中有很多棧幀,每個戰幀里有一個自己的局部變量表)

2.常量池中的對象

3.方法區中靜態引用類型的成員

什么是引用計數呢?

就是使用額外的計數器記錄一個對象被多少個引用指向.如果有新的引用指向這個對象,那引用計數就+1,如果有指向這個對象的引用有減少,則計數也會跟著-1.直到計數為0的時候就意味著沒人引用它,也就成了垃圾了.此時就會被回收.

但是引用計數有兩個比較大的問題:

1.對象如果不大,空間成本高

假如這個對象比較大的話就沒什么問題,假設這個對象是1000Byte,程序計數器是4Byte

那加起來也就1004Byte

但是如果這個對象很小,只有2Byte,那加上計數器(4Byte1)就是6Byte,是原來的3倍大,空間成本太高辣!

2.有循環引用的問題

?在下面的操作之后就會有循環引用的問題.

?

兩個對象現在相互引用了,這樣計數器既不是0,也拿不到對象了,就會一直占著內存.我們就稱為循環引用.

4.垃圾回收的過程

?但是這種清理方法會形成"內存碎片",內存并不是連續的,但是以后new對象的時候要的是連續的空間,所以這樣清理出來的空間也不太能用.

解決方法使用"復制算法"也就是將標記的對象復制到另外一片內存上,再將原來的整片內存清空

?這種方法有點類似順序表的刪除操作,優點是可以有效解決"內存碎片問題",缺點是有點耗時.

?

典型的垃圾回收器:Serial,? ?ParNew,? ?Parallel,? ?Serial Old,? ?Parallel Old,? ?CMS,? ?G1? ?

原文鏈接:https://blog.csdn.net/qq_62592809/article/details/127714582

欄目分類
最近更新