JVM垃圾回收筆記02-垃圾回收器

文章目錄

  • 前言
  • 1.串行(Serial 收集器/Serial Old 收集器)
    • Serial 收集器
    • Serial Old 收集器
    • 相關參數
      • -XX:+UseSerialGC
  • 2.吞吐量優先(Parallel Scavenge 收集器/Parallel Old 收集器)
    • Parallel Scavenge 收集器
    • Parallel Old 收集器
    • 相關參數
      • -XX:+UseParallelGC ~ -XX:+UseParallelOldGC
      • -XX:+UseAdaptiveSizePolicy
      • -XX:GCTimeRatio=ratio
      • -XX:MaxGCPauseMillis=ms
      • -XX:ParallelGCThreads=n
  • 3.響應時間優先(ParNew 收集器/CMS 收集器)
    • CMS 收集器
    • 相關參數
      • -XX:+UseConcMarkSweepGC ~ -XX:+UseParNewGC ~ SerialOld
      • -XX:ParallelGCThreads=n ~ -XX:ConcGCThreads=threads
      • -XX:CMSInitiatingOccupancyFraction=percent
      • -XX:+CMSScavengeBeforeRemark
  • 4.G1(Garbage First收集器)
    • 前言
    • 介紹
    • G1 VS CMS
    • 1.Young Collection
    • 2.Young Collection + CM
    • 3.Mixed Collection
    • 4.Full GC
    • 5.Remark(重新標記階段)
  • ZGC 收集器


前言

如果說回收(收集)算法是內存回收的方法論,那么垃圾回收(收集)器就是內存回收的具體實現。
雖然有各種的收集器,但并非要挑選出一個最好的收集器。因為直到現在為止還沒有最好的垃圾收集器出現,更加沒有萬能的垃圾收集器,我們能做的就是根據具體應用場景選擇適合自己的垃圾收集器。試想一下:如果有一種四海之內、任何場景下都適用的完美收集器存在,那么我們的 HotSpot 虛擬機就不會實現那么多不同的垃圾收集器了。
JDK 默認垃圾收集器(使用 java -XX:+PrintCommandLineFlags -version 命令查看):

  • JDK 8: Parallel Scavenge(新生代)+ Parallel Old(老年代)
  • JDK 9 ~ JDK22: G1

1.串行(Serial 收集器/Serial Old 收集器)

Serial 收集器

Serial(串行)收集器是最基本、歷史最悠久的垃圾收集器了。大家看名字就知道這個收集器是一個單線程收集器了。它的 “單線程” 的意義不僅僅意味著它只會使用一條垃圾收集線程去完成垃圾收集工作,更重要的是它在進行垃圾收集工作的時候必須暫停其他所有的工作線程( “Stop The World” ),直到它收集結束。
新生代采用標記-復制算法,老年代采用標記-整理算法
在這里插入圖片描述
因為Serial(串行)收集器出現的 Stop The World 帶來的不良用戶體驗,所以在后續的垃圾收集器設計中停頓時間在不斷縮短(仍然還有停頓,尋找最優秀的垃圾收集器的過程仍然在繼續)。
Serial 收集器優點:它簡單而高效(與其他收集器的單線程相比)。Serial 收集器由于沒有線程交互的開銷,自然可以獲得很高的單線程收集效率。Serial 收集器對于運行在 Client 模式下的虛擬機來說是個不錯的選擇。

Serial Old 收集器

Serial 收集器的老年代版本,它同樣是一個單線程收集器。它主要有兩大用途:
一種用途是在 JDK1.5 以及以前的版本中與 Parallel Scavenge 收集器搭配使用,另一種用途是作為 CMS 收集器的后備方案。
在這里插入圖片描述

相關參數

-XX:+UseSerialGC

-XX:+UseSerialGC 實際上是指定使用Serial(年輕代)和Serial Old(老年代)的組合。這種設置適合于數據量較小、對應用的停頓時間要求不高且資源受限(如CPU核心數量有限)的環境。

2.吞吐量優先(Parallel Scavenge 收集器/Parallel Old 收集器)

JDK1.8中默認使用收集器為Parallel Scavenge + Parallel Old收集器組合
使用 java -XX:+PrintCommandLineFlags -version 命令查看

-XX:InitialHeapSize=262921408 -XX:MaxHeapSize=4206742528 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)

JDK1.8 默認使用的是 Parallel Scavenge + Parallel Old,如果指定了-XX:+UseParallelGC 參數,則默認指定了-XX:+UseParallelOldGC,可以使用-XX:-UseParallelOldGC 來禁用該功能

Parallel Scavenge 收集器

Parallel Scavenge 收集器是使用標記-復制算法的多線程收集器,Parallel Scavenge 收集器關注點是吞吐量(高效率的利用 CPU)。CMS 等垃圾收集器的關注點更多的是用戶線程的停頓時間(提高用戶體驗)。
所謂吞吐量就是 CPU 中用于運行用戶代碼的時間與 CPU 總消耗時間的比值。
在這里插入圖片描述
Parallel Scavenge 收集器提供了很多參數供用戶找到最合適的停頓時間或最大吞吐量,如果對于收集器運作不太了解,手工優化存在困難的時候,使用 Parallel Scavenge 收集器配合自適應調節策略,把內存管理優化交給虛擬機去完成也是一個不錯的選擇。
新生代采用標記-復制算法,老年代采用標記-整理算法
在這里插入圖片描述

Parallel Old 收集器

Parallel Scavenge 收集器的老年代版本。使用多線程和“標記-整理”算法。在注重吞吐量以及 CPU 資源的場合,都可以優先考慮 Parallel Scavenge 收集器和 Parallel Old 收集器。
在這里插入圖片描述

相關參數

-XX:+UseParallelGC ~ -XX:+UseParallelOldGC

解釋:UseParallelGC:工作于新生代,復制算法
UseParallelOldGC:工作于老年代,標記整理算法
注意:開啟其中一個會自動開啟另一個

-XX:+UseAdaptiveSizePolicy

  • 功能:
    • 啟用自適應大小調整(新生代)策略。該策略會根據運行時的統計信息動態調整新生代(Young Generation)的大小(Eden 區和 Survivor 區)、晉升老年代的閾值等內存分配參數。JVM 會根據當前垃圾回收的性能表現自動調整這些參數,以達到更好的性能優化效果。
    • 當啟用此參數時,JVM 會根據應用程序的行為和垃圾回收統計數據,嘗試找到最優的內存分配比例和晉升閾值,而無需手動指定諸如 -Xmn(新生代大小)或 -XX:SurvivorRatio 等參數。

-XX:GCTimeRatio=ratio

  • 功能:
    • 該參數用于設置吞吐量目標,它是一個控制垃圾回收時間占總運行時間比例的參數。它表示允許的最大垃圾回收時間與總運行時間的比例。
    • 具體計算方式為 1 / (1 + ratio)。例如,如果你設置 ratio = 19,那么最大總垃圾回收時間占總運行時間的比例為 1 / (1 + 19) = 5%
    • JVM 會盡量調整垃圾回收器的工作,以確保垃圾回收時間不超過總運行時間的這個比例,從而保證應用程序的吞吐量,提高程序執行效率。

-XX:MaxGCPauseMillis=ms

  • 功能:
    • 設定垃圾回收的最大暫停時間目標,單位是毫秒。JVM 會盡力將垃圾回收的暫停時間控制在這個目標值以內。默認200ms
    • 當設置此參數后,JVM 會調整堆內存大小、新生代和老年代的比例等,使每次垃圾回收的暫停時間盡可能不超過該值。
    • 然而,需要注意的是,為了達到這個目標,可能會導致更頻繁的垃圾回收操作,或者減少堆內存的使用量,因此需要根據實際情況進行權衡,避免因過度追求低暫停時間而影響整體性能。

注意:-XX:MaxGCPauseMillis=ms和-XX:GCTimeRatio=ratio會有沖突。
當調整 -XX:MaxGCPauseMillis 以追求更短的暫停時間時,可能會影響 -XX:GCTimeRatio 所期望的吞吐量目標。

因為為了達到更短的暫停時間,可能會頻繁進行垃圾回收,這會增加垃圾回收的總時間,導致垃圾回收時間占總運行時間的比例增加,從而可能無法達到 -XX:GCTimeRatio 設定的吞吐量目標。

反之,當調整 -XX:GCTimeRatio 以提高吞吐量時(一般會將堆內存增大),可能會導致單次垃圾回收的暫停時間變長(堆內存變大導致單次時間變長),從而可能超過 -XX:MaxGCPauseMillis 設定的暫停時間限制,影響對響應時間敏感的應用程序的性能。

-XX:ParallelGCThreads=n

  • 功能:
    • 用于設置并行垃圾回收器的線程數量為 n。
    • 在使用并行垃圾回收器(如 Parallel Scavenge 或 Parallel Old)時,該參數決定了在進行垃圾回收時同時運行的線程數量。
    • 通常,n 的值可以根據 CPU 核心數來確定。如果不設置此參數,JVM 會根據實際的 CPU 核心數自動設置一個合適的值。在多核心的環境下,增加并行垃圾回收線程的數量可以提高垃圾回收的效率,但過多的線程也可能會帶來額外的線程切換開銷,所以要根據實際硬件和應用程序的特點來合理設置此參數。

3.響應時間優先(ParNew 收集器/CMS 收集器)

ParNew 收集器其實就是 Serial 收集器的多線程版本,除了使用多線程進行垃圾收集外,其余行為(控制參數、收集算法、回收策略等等)和 Serial 收集器完全一樣。
ParNew 收集器采用標記-復制算法
在這里插入圖片描述
它是許多運行在 Server 模式下的虛擬機的首要選擇,除了 Serial 收集器外,只有它能與 CMS 收集器配合工作

ParNew收集器是激活CMS后(使用-XX:+UseConcMarkSweepGC選項)的默認新生代收集器,也可以使用-XX:+/-UseParNewGC選項來強制指定或者禁用它。

自JDK 9開始還取消了ParNew加Serial Old以及Serial加CMS這兩組收集器組合的支持,并直接取消了-XX:+UseParNewGC參數,這意味著ParNew和CMS從此只能互相搭配使用,再也沒有其他收集器能夠和它們配合了。

讀者也可以理解為從此以后,ParNew合并入CMS,成為它專門處理新生代的組成部分。ParNew可以說是HotSpot虛擬機中第一款退出歷史舞臺的垃圾收集器。

CMS 收集器

CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。它非常符合在注重用戶體驗的應用上使用。

CMS(Concurrent Mark Sweep)收集器是 HotSpot 虛擬機第一款真正意義上的并發收集器,它第一次實現了讓垃圾收集線程與用戶線程(基本上)同時工作。

遺憾的是,CMS作為老年代的收集器,卻無法與JDK 1.4.0中已經存在的新生代收集器Parallel Scavenge配合工作,所以在JDK 5中使用CMS來收集老年代的時候,新生代只能選擇ParNew或者Serial收集器中的一個。

從名字中的Mark Sweep這兩個詞可以看出,CMS 收集器是一種 “標記-清除”算法實現的,它的運作過程相比于前面幾種垃圾收集器來說更加復雜一些。整個過程分為四個步驟(其中初始標記、重新標記這兩個步驟仍然需要“Stop The World”):

  • 初始標記: 短暫停頓,標記直接與 root 相連的對象(根對象);
  • 并發標記: 同時開啟 GC 和用戶線程,用一個閉包結構去記錄可達對象。但在這個階段結束,這個閉包結構并不能保證包含當前所有的可達對象。因為用戶線程可能會不斷的更新引用域,所以 GC 線程無法保證可達性分析的實時性。所以這個算法里會跟蹤記錄這些發生引用更新的地方。(并發標記階段就是從GC Roots的直接關聯對象開始遍歷整個對象圖的過程,這個過程耗時較長但是不需要停頓用戶線程,可以與垃圾收集線程一起并發運行;)
  • 重新標記: 重新標記階段就是為了修正并發標記期間因為用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記階段的時間稍長,遠遠比并發標記階段時間短
  • 并發清除: 開啟用戶線程,同時 GC 線程開始對未標記的區域做清掃。(并發清除階段清理刪除掉標記階段判斷的已經死亡的對象,由于不需要移動存活對象,所以這個階段也是可以與用戶線程同時并發的。)

總結
初始標記時耗費時間特別少,只是標記根對象。之后進行并發標記,此時用戶線程也在運行,所以可能會改變對象的引用,所以之后需要重新標記(也是stop-the-world),之后在并發清理。
在并發清理時用戶線程產生的垃圾成為浮動垃圾,只能在下次垃圾回收時清理。
注意:該垃圾回收器對CPU的占用并不高,但是此時用戶線程也會運行,又因為兩者同時運行,所以在垃圾回收時,會對程序的吞吐量有影響。
在這里插入圖片描述
CMS主要優點:并發收集、低停頓。但是它有下面三個明顯的缺點:

  • 對 CPU 資源敏感;
  • 無法處理浮動垃圾;
  • 它使用的回收算法-“標記-清除”算法會導致收集結束時會有大量空間碎片產生。

CMS 垃圾回收器在 Java 9 中已經被標記為過時(deprecated),并在 Java 14 中被移除。

由于CMS收集器無法處理“浮動垃圾”(Floating Garbage),有可能出現“Con-current Mode Failure”失敗進而導致另一次完全“Stop The World”的Full GC的產生。

在CMS的并發標記和并發清理階段,用戶線程是還在繼續運行的,程序在運行自然就還會伴隨有新的垃圾對象不斷產生,但這一部分垃圾對象是出現在標記過程結束以后,CMS無法在當次收集中處理掉它們,只好留待下一次垃圾收集時再清理掉。

并行和并發概念補充:
并行(Parallel):指多條垃圾收集線程并行工作,但此時用戶線程仍然處于等待狀態。
并發(Concurrent):指用戶線程與垃圾收集線程同時執行(但不一定是并行,可能會交替執行),用戶程序在繼續運行,而垃圾收集器運行在另一個 CPU 上。

相關參數

-XX:+UseConcMarkSweepGC ~ -XX:+UseParNewGC ~ SerialOld

UseConcMarkSweepGC:工作于老年代,基于標記清除的并發回收器,該垃圾回收器在運行時,其他用戶線程也可以同時運行,但是在某些階段還是需要stop-the-world。
UseParNewGC:工作于新生代,基于復制算法的垃圾回收器
SerialOld:UseConcMarkSweepGC回收器在有些情況下會出現并發失敗的問題,此時會采取補救的措施,老年代會從并發回收器退化到單線程回收器。
并發失敗的原因有:因為使用的基于標記清除的并發回收器,所以可能是因為內存碎片導致的,此時退化為單線程的垃圾回收器進行內存整理

-XX:ParallelGCThreads=n ~ -XX:ConcGCThreads=threads

ParallelGCThreads=n:并行線程數
ConcGCThreads=threads:并發GC線程數,一般設置為并行線程數的四分之一

-XX:CMSInitiatingOccupancyFraction=percent

在并發清理時用戶線程產生的垃圾成為浮動垃圾,只能在下次垃圾回收時清理。如設置這個參數為占用老年代內存80%時會觸發垃圾回收,預留一些空間存放浮動垃圾

-XX:+CMSScavengeBeforeRemark

在重新標記之前對新生代進行一次垃圾回收

4.G1(Garbage First收集器)

前言

在G1收集器出現之前的所有其他收集器,包括CMS在內,垃圾收集的目標范圍要么是整個新生代(Minor GC),要么就是整個老年代(Major GC),再要么就是整個Java堆(Full GC)。

而G1跳出了這個樊籠,它可以面向堆內存任何部分來組成回收集(Collection Set,一般簡稱CSet)進行回收,衡量標準不再是它屬于哪個分代,而是哪塊內存中存放的垃圾數量最多,回收收益最大,這就是G1收集器的Mixed GC模式。G1開創的基于Region的堆內存布局是它能夠實現這個目標的關鍵。

雖然G1也仍是遵循分代收集理論設計的,但其堆內存的布局與其他收集器有非常明顯的差異:G1不再堅持固定大小以及固定數量的分代區域劃分,而是把連續的Java堆劃分為多個大小相等的獨立區域(Region),每一個Region都可以根據需要,扮演新生代的Eden空間、Survivor空間,或者老年代空間。

收集器能夠對扮演不同角色的Region采用不同的策略去處理,這樣無論是新創建的對象還是已經存活了一段時間、熬過多次收集的舊對象都能獲取很好的收集效果。

Region中還有一類特殊的Humongous區域,專門用來存儲大對象。G1認為只要大小超過了一個Region容量一半的對象即可判定為大對象。
每個Region的大小可以通過參數-XX:G1HeapRegionSize設定,取值范圍為1MB~32MB,且應為2的N次冪。而對于那些超過了整個Region容量的超級大對象,將會被存放在N個連續的Humongous Region之中,G1的大多數行為都把Humongous Region作為老年代的一部分來進行看待。

介紹

G1 (Garbage-First) 是一款面向服務器的垃圾收集器,主要針對配備多顆處理器及大容量內存的機器. 以極高概率滿足 GC 停頓時間要求的同時,還具備高吞吐量性能特征
被視為 JDK1.7 中 HotSpot 虛擬機的一個重要進化特征。它具備以下特點:

  • 并行與并發:G1 能充分利用 CPU、多核環境下的硬件優勢,使用多個 CPU(CPU 或者 CPU 核心)來縮短 Stop-The-World 停頓時間。部分其他收集器原本需要停頓 Java 線程執行的 GC 動作,G1 收集器仍然可以通過并發的方式讓 java 程序繼續執行。
  • 分代收集:雖然 G1 可以不需要其他收集器配合就能獨立管理整個 GC 堆,但是還是保留了分代的概念。
  • 空間整合:與 CMS 的“標記-清除”算法不同,G1 從整體來看是基于“標記-整理”算法實現的收集器;從局部上來看是基于“標記-復制”算法實現的。
  • 可預測的停頓:這是 G1 相對于 CMS 的另一個大優勢,降低停頓時間是 G1 和 CMS 共同的關注點,但 G1 除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為 M 毫秒的時間片段內,消耗在垃圾收集上的時間不得超過 N 毫秒。

G1 收集器的運作大致分為以下幾個步驟:

  • 初始標記: 短暫停頓(Stop-The-World,STW),標記從 GC Roots 可直接引用的對象,即標記所有直接可達的活躍對象
  • 并發標記:與應用并發運行,標記所有可達對象。 這一階段可能持續較長時間,取決于堆的大小和對象的數量。
  • 最終標記: 短暫停頓(STW),處理并發標記階段結束后殘留的少量未處理的引用變更。
  • 篩選回收:根據標記結果,選擇回收價值高的區域,復制存活對象到新區域,回收舊區域內存。這一階段包含一個或多個停頓(STW),具體取決于回收的復雜度。
    在這里插入圖片描述
    G1 收集器在后臺維護了一個優先列表,每次根據允許的收集時間,優先選擇回收價值最大的 Region(這也就是它的名字 Garbage-First 的由來) 。這種使用 Region 劃分內存空間以及有優先級的區域回收方式,保證了 G1 收集器在有限時間內可以盡可能高的收集效率(把內存化整為零)。
    從 JDK9 開始,G1 垃圾收集器成為了默認的垃圾收集器。

G1 VS CMS

目前在小內存應用上CMS的表現大概率仍然要會優于G1,而在大內存應用上G1則大多能發揮其優勢,這個優劣勢的Java堆容量平衡點通常在6GB至8GB之間。當然,以上這些也僅是經驗之談,不同應用需要量體裁衣地實際測試才能得出最合適的結論,隨著HotSpot的開發者對G1的不斷優化,也會讓對比結果繼續向G1傾斜。

在這里插入圖片描述

1.Young Collection

  • 會 STW

G1會把堆內存劃分為一個個大小相等的區域,每個區域都可以獨立作為伊甸園、幸存區、老年代。
在這里插入圖片描述
以上白色區域表示空閑區域,E則代表伊甸園區域,新創建的對象放在其中。
當伊甸園逐漸被占滿,就會觸發一次新生代的垃圾回收

在這里插入圖片描述
垃圾回收會通過復制算法將幸存對象放入幸存區S

在這里插入圖片描述
當幸存區中對象也比較多時,會觸發新生代垃圾回收,將一些對象晉升(老年代)O區域中,不滿足晉升條件的會將對象復制到其他的幸存區中。

2.Young Collection + CM

  • 在 Young GC 時會進行 GC Root (根對象)的初始標記
  • 老年代占用堆空間比例達到閾值時,進行并發標記(不會 STW),由下面的 JVM 參數決定
    -XX:InitiatingHeapOccupancyPercent=percent (默認45%)
    在這里插入圖片描述

3.Mixed Collection

會對 E、S、O 進行全面垃圾回收

  • 最終標記(Remark)會 STW
  • 拷貝存活(Evacuation)會 STW
    -XX:MaxGCPauseMillis=ms
    在這里插入圖片描述
  • 伊甸園S中的幸存對象會被復制算法復制到幸存區中,幸存區S中不夠年齡的對象也會被復制到其他幸存區中,符合晉升條件的對象會晉升到老年代O中。
  • 老年代垃圾回收時也采用的復制算法,將幸存對象復制到新的O中,老年代因為需要滿足最大暫停時間MaxGCPauseMillis,所以會有選擇的進行回收。
  • 因為有時候堆內存太大了,導致老年代的回收時間比較長。所以G1會從老年代中選擇回收價值最高(垃圾最多的,可以釋放更多的空間)的區域,復制的區域少了,時間自然就變短了。
  • 如果回收全部老年代也滿足最大暫停時間,那么會回收所有老年代區域。

4.Full GC

當G1老年代內存不足時,老年代占用堆空間比例達到閾值(默認45%)時,進行并發標記。后續進行混合收集的階段。

G1Full GC的時機:當垃圾回收的速度跟不上垃圾產生的速度時(并發回收失敗)。此時會退化為串行回收階段

5.Remark(重新標記階段)

  • remark階段就是為了防止出現被引用的被當成垃圾回收,沒有被引用的沒有被垃圾回收的情況。
  • 當對象的引用發生改變時,JVM會加入一個寫屏障。如B對象被A對象引用,則會在引用上加上寫屏障。
  • 當觸發寫屏障后,會將B對象加入一個隊列中,并變為灰色表示沒有處理完。等到并發標記結束后,進入重新標記階段,重新標記階段會SSW,暫停其他用戶線程。將隊列中的對象進行重新標記。隊列的名稱叫satb_mark_queue
    在這里插入圖片描述
    以上圖為并發標記階段,對象的處理狀態。
  • 黑色表示處理完成,并且被引用。所以表示垃圾回收后會被保留下來的對象。
  • 灰色表示處理當中的。
  • 白色表示尚未處理的。
  • 灰色、白色如果被引用,則最終會變成黑色。如果沒有被引用則變為白色(并發標記后)被當成垃圾回收。

ZGC 收集器

與 CMS 中的 ParNew 和 G1 類似,ZGC 也采用標記-復制算法,不過 ZGC 對該算法做了重大改進。

ZGC 可以將暫停時間控制在幾毫秒以內,且暫停時間不受堆內存大小的影響,出現 Stop The World 的情況會更少,但代價是犧牲了一些吞吐量。ZGC 最大支持 16TB 的堆內存。

ZGC 在 Java11 中引入,處于試驗階段。經過多個版本的迭代,不斷的完善和修復問題,ZGC 在 Java15 已經可以正式使用了。
不過,默認的垃圾回收器依然是 G1。你可以通過下面的參數啟用 ZGC:

java -XX:+UseZGC className

java -XX:+UseZGC className
在 Java21 中,引入了分代 ZGC,暫停時間可以縮短到 1 毫秒以內。
你可以通過下面的參數啟用分代 ZGC:

java -XX:+UseZGC -XX:+ZGenerational className

相關文章:
JVM內存結構

  • JVM內存結構筆記01-運行時數據區域
  • JVM內存結構筆記02-堆
  • JVM內存結構筆記03-方法區
  • JVM內存結構筆記04-字符串常量池
  • JVM內存結構筆記05-直接內存
  • JVM內存結構筆記06-HotSpot虛擬機對象探秘
  • JVM中常量池和運行時常量池、字符串常量池三者之間的關系

JVM垃圾回收

  • JVM垃圾回收筆記01-垃圾回收算法
  • JVM垃圾回收筆記02-垃圾回收器

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73567.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73567.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73567.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

圖解AUTOSAR_SWS_UDPNetworkManagement

AUTOSAR UDP 網絡管理 (UdpNm) 技術詳解 基于 AUTOSAR 規范的 UDP 網絡管理模塊可視化指南 目錄 AUTOSAR UDP 網絡管理 (UdpNm) 技術詳解 目錄1. 概述2. UdpNm 狀態機 2.1 狀態機概述2.2 主要狀態說明2.3 狀態轉換機制2.4 并行狀態3. UdpNm 架構設計 3.1 架構概述3.2 接口設計3…

android 圖形開發的技能學習路線

需要以下幾個方面的知識: OpenGL ES的基礎和高級應用圖形渲染管線的工作原理3D數學(矩陣、向量、四元數)著色器編程(GLSL)libGDX框架的使用和定制性能優化和內存管理跨平臺渲染技術 接下來,考慮如何結構化…

使用AI一步一步實現若依(26)

功能26:新增一個新員工培訓頁面 功能25:角色管理 功能24:菜單管理 功能23:從后端獲取路由/菜單數據 功能22:用戶管理 功能21:使用axios發送請求 功能20:使用分頁插件 功能19:集成My…

vue響應式原理剖析

一、什么是響應式? 我們先來看一下響應式意味著什么?我們來看一段代碼: m有一個初始化的值,有一段代碼使用了這個值; 那么在m有一個新的值時,這段代碼可以自動重新執行; let m = 20 console.log(m) console.log(m * 2)m = 40上面的這樣一種可以自動響應數據變量的代碼機…

無人機航電系統電池技術解析!

1. 常用電池類型 鋰聚合物電池(LiPo) 特點:高能量密度、輕量化、放電效率高,是目前主流選擇。 缺點:對過充/過放敏感,需嚴格管理,存在輕微膨脹或起火風險。 鋰離子電池(Li-ion…

ubuntu下終端打不開的排查思路和解決方法

問題現象描述:ubuntu開機后系統桌面顯示正常,其他圖形化的app也都能打開無異常,唯獨只有terminal終端打不開,無論是鼠標點擊終端軟件,還是ctrlaltt,還是altF2后輸入gnome-terminal后按回車,這三…

Maven入門

1、簡介 Apache Maven是一個項目管理及自動構建工具,由Apache軟件基金會所提供。基于項目對象模型(縮寫:POM)概念,Maven利用一個中央信息片斷能管理一個項目的構建、報告和文檔等步驟。 2、作用 1)依賴導…

Rk3588,Opencv讀取Gmsl相機,Rga yuv422轉換rgb (降低CPU使用率)

RK3588, 使用OpenCv 讀取 gmsl 相機,獲得yuv422格式圖像, 使用 rga 轉換 rgb 圖像。減少cpu占用率. 查看相機信息 v4l2-ctl --all -d /dev/cam0 , 查看自己相機分辨率,輸出格式等信息,對應修改后續代碼測試… Driver Info:Driver name : rkcifCard type : rkc…

鴻蒙相機開發實戰:從設備適配到性能調優 —— 我的 ArkTS 錄像功能落地手記(API 15)

引言:為什么我要寫這份開發指南? 作為一名老技術,最近特別喜歡研究鴻蒙相機功能,而且目前已經更新到API15了,那么咱們更要好好研究一下。而且從手持云臺到車載記錄儀,每個項目都面臨獨特挑戰:車…

【NLP 49、提示工程 prompt engineering】

目錄 一、基本介紹 語言模型生成文本的基本特點 提示工程 prompt engineering 提示工程的優勢 使用注意事項 ① 安全問題 ② 可信度問題 ③ 時效性與專業性 二、應用場景 能 ≠ 適合 應用場景 —— 百科知識 應用場景 —— 寫文案 應用場景 —— 解釋 / 編寫…

數字轉換(c++)

【題目描述】 如果一個數 xx 的約數和 yy (不包括他本身)比他本身小,那么 xx 可以變成 yy ,yy 也可以變成 xx 。例如 44 可以變為 33 ,11 可以變為 77 。限定所有數字變換在不超過 nn 的正整數范圍內進行,…

如何同步fork的更新

當你fork了一個代碼倉庫后,要將其與原始源碼保持同步,可以按照以下步驟進行操作: 1. 添加原始倉庫作為遠程源 在本地命令行中,進入到你fork后的代碼倉庫目錄,然后使用以下命令添加原始倉庫(通常稱為upstr…

CentOS系統下安裝tesseract-ocr5.x版本

CentOS系統下安裝tesseract-ocr5.x版本 安裝依賴包: yum update -y yum install autoconf automake libtool libjpeg-devel libpng-devel libtiff-devel zlib-devel yum install automake libtool bzip2 -y手動編譯安裝GCC(因系統默認安裝的GCC版本比較…

MyBatis打印SQL日志的配置

配置MyBatis打印日志的步驟如下&#xff0c;支持多種日志框架&#xff08;如Logback、Log4j2等&#xff09;&#xff1a; 一、選擇日志框架并添加依賴&#xff08;以常見組合為例&#xff09; 1. Logback&#xff08;推薦&#xff09; <!-- Maven 依賴 --> <depende…

SpringCould微服務架構之Docker(3)

1&#xff09;什么是鏡像和容器&#xff1f; 2&#xff09;DockerHub&#xff1a; 3&#xff09;docker的架構如下&#xff1a;

智慧高速,安全護航:視頻監控平臺助力高速公路高效運營

隨著我國高速公路里程的不斷增長&#xff0c;交通安全和運營效率面臨著前所未有的挑戰。傳統的監控方式已難以滿足現代化高速公路管理的需求&#xff0c;而監控視頻平臺的出現&#xff0c;則為高速公路的安全運營提供了強有力的技術支撐。高速公路視頻監控聯網解決方案 高速公路…

vue對文件進行加密,后臺解密后保存

為什么要做加密解密&#xff1f;主要是避免第三方檢測系統&#xff08;WAF&#xff09;檢測出文件有問題&#xff0c;但是文件是用戶上傳的&#xff0c;我們控制不了這些文件&#xff0c;所以主要是通過對用戶上傳文件進行加密&#xff0c;后臺解密后存儲。 前端&#xff1a; …

AI 在測試中的應用:從自動化到智能化的未來

閱讀原文 在上一篇中&#xff0c;我們探討了測試左移與右移如何構建質量保障的全流程閉環。現在&#xff0c;我們將目光投向更前沿的領域——AI在測試中的應用。這不僅是技術的演進&#xff0c;更是測試理念的革命&#xff1a;從"自動化執行"到"智能決策"…

Python:計算機二級:簡單應用

文章目錄 簡單應用第一題第二題第三題第四題題型共同特點核心知識點講解解題通用方法步驟 操作的難點1.數據的統計2.數據的篩選1. **條件判斷篩選**2. **結合文件操作篩選**3. **多條件組合篩選** 類似題目其它一題 簡單應用 第一題 題目 在考生文件夾下的PY202.py文件中&…

SQL Server 2022常見問題解答

以下是SQL Server 2022的常見問題解答,按主題分類整理: 一、安裝與升級 SQL Server 2022的系統要求是什么? 支持的操作系統:Windows Server 2016及以上、Linux(Ubuntu 20.04/22.04, RHEL 8/9等)。內存:至少4GB(建議8GB+)。磁盤空間:6GB以上,具體取決于安裝組件。如何…