偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我是這樣跟面試官講垃圾回收的

云計(jì)算 虛擬化
垃圾回收機(jī)制是什么?我們?yōu)槭裁匆獙W(xué)習(xí)垃圾回收機(jī)制?今天我們就帶著這兩個(gè)問題一起來看看。

[[356806]]

本文轉(zhuǎn)載自微信公眾號(hào)「故里學(xué)Java」,作者故里學(xué)Java 。轉(zhuǎn)載本文請(qǐng)聯(lián)系故里學(xué)Java公眾號(hào)。

垃圾回收機(jī)制是什么?我們?yōu)槭裁匆獙W(xué)習(xí)垃圾回收機(jī)制?今天我們就帶著這兩個(gè)問題一起來看看。

在我們?nèi)粘5拈_發(fā)過程中,并不會(huì)過多的關(guān)注對(duì)象的回收和釋放,JVM就可以幫助我們來完成垃圾,減少了我們很多的工作量,仿佛垃圾回收離我們很遠(yuǎn),其實(shí)垃圾回收機(jī)制是我們從初級(jí)到中高級(jí)開發(fā)必須掌握的。把回收對(duì)象的任務(wù)完全交給JVM,看似解放了,其實(shí)也增加了不確定性,事情并不是什么時(shí)候都是完美的,在現(xiàn)如今各種復(fù)雜業(yè)務(wù)場(chǎng)景下,不合適的垃圾回收算法及策略,往往是導(dǎo)致我們系統(tǒng)性能瓶頸的主要原因。

垃圾回收也不能一概而論,不同的業(yè)務(wù)場(chǎng)景采取不同的措施,如果業(yè)務(wù)場(chǎng)景對(duì)內(nèi)存的要求比較高,就需要提高對(duì)象的回收效率,如果是CPU使用率高,這個(gè)時(shí)候就要降低垃圾回收頻率。

我們都知道,JVM的內(nèi)存中有多個(gè)區(qū)域,垃圾回收主要是看堆和方法區(qū)的內(nèi)存,因?yàn)槠渌麉^(qū)域如程序計(jì)數(shù)器、虛擬機(jī)棧和本地方法棧等區(qū)域的內(nèi)存具有確定性,所以我們要把目光主要放在堆中的對(duì)象回收和方法區(qū)的廢棄常量的回收。

JVM如何判斷一個(gè)對(duì)象可以回收的?

最開始接觸垃圾回收的時(shí)候,應(yīng)該都聽過,對(duì)象沒有被引用的時(shí)候就可以被回收,但是怎么判斷對(duì)象是否被引用,主要有兩種方式:引用計(jì)數(shù)算法和可達(dá)性分析算法。

**引用計(jì)數(shù)算法:**所謂的引用計(jì)數(shù)算法,就是通過一個(gè)對(duì)象的引用計(jì)數(shù)器來判斷該對(duì)象是否被引用,對(duì)象被引用的時(shí)候,計(jì)數(shù)器就加1,引用失效計(jì)數(shù)器就減1。計(jì)數(shù)器的值為0 的時(shí)候就說明這個(gè)對(duì)象沒有被引用了,可以被JVM回收了。需要注意的是,引用計(jì)數(shù)算法雖然實(shí)現(xiàn)方式簡(jiǎn)單,但是會(huì)出現(xiàn)循環(huán)引用的問題。

**可達(dá)性分析算法:**可達(dá)性分析算法的基礎(chǔ)是GC Roots,是所有對(duì)象的跟對(duì)象,在JVM加載時(shí),會(huì)創(chuàng)建一些對(duì)象引用正常對(duì)象,這些對(duì)象作為這些正常對(duì)象的起始點(diǎn),在垃圾回收時(shí),JVM會(huì)從GC Roots開始向下搜索,如果一個(gè)對(duì)象到GC Roots沒有任何引用鏈相連時(shí),就證明這個(gè)對(duì)象可以回收了。

垃圾回收線程是如何回收對(duì)象的?

JVM去回收對(duì)象主要遵從兩個(gè)特性:自動(dòng)性、不可預(yù)期性。

**自動(dòng)性:**JVM會(huì)創(chuàng)建一個(gè)系統(tǒng)級(jí)的線程來跟蹤每一塊被分配出去的內(nèi)存,在JVM空閑時(shí),就會(huì)自動(dòng)的檢查每一塊分配出去的內(nèi)存空間,然后自動(dòng)回收每一塊內(nèi)存。

**不可預(yù)期性:**不可預(yù)期性主要是一個(gè)對(duì)象沒有被引用的時(shí)候,是立馬就被回收的嗎,這個(gè)答案是未知的,有可能立馬就被回收,有可能隔了很久依然在內(nèi)存中。

GC算法

JVM給我們提供了多種回收算法來實(shí)現(xiàn)回收機(jī)制,一般來說,市面上常見的垃圾收集器的回收算法主要分為四類:

標(biāo)記-清除算法(Mark-Sweep)

優(yōu)點(diǎn):不需要移動(dòng)對(duì)象,簡(jiǎn)單高效

確定:標(biāo)記-清除的過程效率低,會(huì)產(chǎn)生內(nèi)存碎片。

復(fù)制算法(Copying)

優(yōu)點(diǎn):簡(jiǎn)單高效,不會(huì)產(chǎn)生內(nèi)存碎片

缺點(diǎn):內(nèi)存使用率低,還有可能產(chǎn)生頻繁復(fù)制的問題。

標(biāo)記-整理算法(Mark-Compact)

優(yōu)點(diǎn):不需要移動(dòng)對(duì)象,效率高,不產(chǎn)生內(nèi)存碎片

缺點(diǎn):需要移動(dòng)局部對(duì)象

分代收集算法(Gennerational Collection)

優(yōu)點(diǎn):分區(qū)回收

缺點(diǎn):對(duì)于長(zhǎng)期存活對(duì)象的回收效果不太好。

了解了四種垃圾收集器的回收算法之后,我們?cè)賮砜纯椿谶@些算法實(shí)現(xiàn)的回收器,簡(jiǎn)單介紹幾種常見的:

衡量GC性能的標(biāo)準(zhǔn)?

垃圾收集器各種各樣的,不同的場(chǎng)景適用不同的回收器,如何挑選合適的垃圾收集器,主要取決于垃圾收集器的三個(gè)指標(biāo):吞吐量、卡頓時(shí)間、垃圾回收頻率。

**吞吐量:**指系統(tǒng)應(yīng)用程序花費(fèi)的時(shí)間和系統(tǒng)運(yùn)行總時(shí)長(zhǎng)的比值,GC 的吞吐量=GC耗時(shí)/系統(tǒng)總運(yùn)行時(shí)間。GC的吞吐量一般不低于95%。

**卡頓時(shí)間:**卡頓時(shí)間是垃圾收集器在工作的時(shí)候,應(yīng)用程序暫停的時(shí)間。一般串行收集器的卡頓時(shí)間較長(zhǎng),并發(fā)收集器的卡頓時(shí)間因?yàn)槭占骱蛻?yīng)用程序交替運(yùn)行,所以卡頓時(shí)間會(huì)比較短,但是效率不如串行的,系統(tǒng)吞吐量會(huì)有所下降。

**垃圾回收頻率:**垃圾回收頻率時(shí)間和卡頓時(shí)間是互相影響的,我們可以通過增大內(nèi)存的方式來降低垃圾回收發(fā)生的頻率,但是內(nèi)存增大后,堆積的對(duì)象就更多,當(dāng)垃圾回收時(shí),卡頓的時(shí)間就會(huì)增加。所以我們要把握增加內(nèi)存的這個(gè)度,來保證正常的垃圾回收頻率即可。

如何查看并分析GC日志?

前邊廢話這么多,估計(jì)很多大兄弟都看煩了,接下來我們來看看如何收集GC日志,并分析GC日志,我們需要JVM參數(shù)來設(shè)置GC日志,需要關(guān)注以下幾個(gè)參數(shù):

  1. -XX:+PrintGC  #輸出GC日志 
  2. -XX:+PrintGCDetails #輸出GC的詳細(xì)日志 
  3. -XX:+PrintGCTimeStamps #輸出GC的時(shí)間戳(以基準(zhǔn)時(shí)間的形式) 
  4. -XX:+PrintGCDateStamps #輸出GC的時(shí)間戳(以日期的形式,如 2020-12-08T23:59:59.234+0800) 
  5. -XX:+PrintHeapAtGC #在進(jìn)行GC的前后打印出堆的信息 
  6. -Xloggc:../logs/gc.log #日志文件的輸出路徑 

我們按需配置參數(shù)即可,打印后的日志,例如下圖:

很短時(shí)間的GC日志我們可以用記事本打開去查看,如果是分析長(zhǎng)時(shí)間的GC日志,再用記事本打開去看就有點(diǎn)困難,我們就需要借助工具來分析,一般省事的可以用GCViewer來打開日志文件,就可以圖形化的查看GC性能。通過工具我們可以看到吞吐量、卡頓時(shí)間、GC頻率,很直觀的查看GC的性能情況。

GCeasy也是一個(gè)更好用的GC日志分析工具,只需要把日志文件壓縮一下,上傳官網(wǎng)就可以在線分析,下邊是我使用一個(gè)本地的GC日志分析的結(jié)果:

GC調(diào)優(yōu)

上邊通過分析GC日志,找出影響性能的問題,接下來就該有針對(duì)性的調(diào)優(yōu)了,簡(jiǎn)單介紹幾種常用的調(diào)優(yōu)策略,主要是降低Minor GC和Full GCd 頻率。

降低Minor GC頻率

我們首先來看,Minor GC主要是針對(duì)Eden區(qū)的對(duì)象回收,由于新生代空間一般比較小,Eden區(qū)很塊就會(huì)滿,就會(huì)導(dǎo)致Minor GC的頻率比較高,我們的解決辦法通常是增大新生代空間來降低Minor GC的頻率。在前邊講衡量GC性能指標(biāo)的時(shí)候,我們提到增大內(nèi)存會(huì)增加回收時(shí)候的卡頓時(shí)間。Minor GC也會(huì)導(dǎo)致應(yīng)用程序的卡頓,只是時(shí)間非常短暫,那么擴(kuò)大Eden區(qū)會(huì)不會(huì)導(dǎo)致Minor GC的時(shí)間增長(zhǎng),還得深入看一下一次Minor GC發(fā)生了什么。

每次Minor GC主要做了兩件事,掃描新生代(A)和復(fù)制存活對(duì)象(B)。其中復(fù)制對(duì)象的耗時(shí)是遠(yuǎn)高于掃描對(duì)象的。我們舉個(gè)例子,如果一個(gè)對(duì)象在Eden區(qū)域存活500ms,Minor GC的頻率是300ms一次,正常情況下,在一次Minor GC中用時(shí)就說A+B的時(shí)間,這個(gè)時(shí)候我們通過gc日志分析,把Eden擴(kuò)容,變成了600ms才進(jìn)行一次Minor GC,此時(shí)這個(gè)對(duì)象在Eden區(qū)中已經(jīng)被回收,就不用復(fù)制對(duì)象了,就省去了復(fù)制存活對(duì)象的時(shí)間,在這一次Minor GC中只是增加了掃描新生代的時(shí)間。

總結(jié):?jiǎn)未?Minor GC 時(shí)間更多取決于 GC 后存活對(duì)象的數(shù)量,而非 Eden 區(qū)的大小。如果堆內(nèi)存中存活時(shí)間比較長(zhǎng)的對(duì)象多,增加年輕代的空間,單次Minor GC的時(shí)間反而會(huì)增加,如果是堆內(nèi)存中短期對(duì)象多,那么擴(kuò)容后,單詞Minor GC的時(shí)間不會(huì)明顯的增加,還降低了Minor GC頻率。

降低Full GC頻率

Full GC的觸發(fā)通常是因?yàn)槎褍?nèi)存空間不足或者老年代對(duì)象太多造成的,F(xiàn)ull GC又會(huì)帶來上下文切換,前邊的文章我們已經(jīng)專門介紹過上下文切換,都知道上下文切換會(huì)降低系統(tǒng)的性能。我們可以通過下邊幾個(gè)方向來降低Full GC的頻率。

減少創(chuàng)建大對(duì)象:有時(shí)候因?yàn)橐恍┚幊塘?xí)慣的問題,為了省事就一次性從數(shù)據(jù)庫查詢一個(gè)大對(duì)象用于web端顯示,這種大對(duì)象會(huì)被直接創(chuàng)建在老年代,哪怕是創(chuàng)建在新生代,由于新生代的空間一般很小,通過一次Minor GC就會(huì)進(jìn)入老年代,這樣的大對(duì)象攢多了就會(huì)觸發(fā)Full GC,所以還是要養(yǎng)成良好的習(xí)慣,減少一些不必要字段的查詢。

增大對(duì)內(nèi)存空間:堆內(nèi)存不足這種情況就直接增大堆內(nèi)存的空間,把初始化內(nèi)存空間就設(shè)置成最大堆內(nèi)存空間,這樣就可以顯著降低Full GC頻率/

合適的GC回收器:上邊我們也介紹了多種回收器,根據(jù)我們的業(yè)務(wù)場(chǎng)景,選擇合適的回收器往往可以達(dá)到不錯(cuò)的效果。

總結(jié)

垃圾回收是一門復(fù)雜的學(xué)問,需要不斷地去練習(xí),去實(shí)踐。看完這篇文章想必對(duì)垃圾回收有了一定了解了吧,趕快行動(dòng)起來,先拿公司的開發(fā)環(huán)境練練手。

 

責(zé)任編輯:武曉燕 來源: 故里學(xué)Java
相關(guān)推薦

2021-12-02 18:20:25

算法垃圾回收

2021-02-03 15:30:10

面試垃圾回收器前端

2020-02-03 17:22:34

垃圾回收原理種類

2022-04-19 07:31:28

事務(wù)隔離機(jī)制數(shù)據(jù)庫

2024-03-05 07:31:59

CASvalue原子性

2019-08-23 09:20:35

Spring 5編程Java

2021-12-02 08:19:06

MVCC面試數(shù)據(jù)庫

2021-11-29 10:55:11

線程池Java面試

2025-02-27 00:08:24

2020-07-02 07:52:11

RedisHash映射

2017-03-16 15:27:10

面試官測(cè)試技術(shù)

2021-09-07 10:44:33

Java 注解開發(fā)

2022-10-09 08:38:17

消息隊(duì)列面試官模式

2021-02-19 10:02:57

HTTPSJava安全

2024-02-04 10:08:34

2020-02-25 16:56:02

面試官有話想說

2024-12-25 15:44:15

2025-10-21 08:06:20

2021-12-08 06:53:29

面試動(dòng)態(tài)代理

2024-02-22 15:36:23

Java內(nèi)存模型線程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)