A. cms垃圾回收演算法在gc過程中哪幾個階段會暫停
Phase 1: Initial Mark(初始化標記)和 Phase 5: Final Remark(重新標記)這兩個階段會發生stop-the-world,暫停所有應用線程。
B. JVM的垃圾演算法有哪幾種
一、垃圾收集器概述
如上圖所示,垃圾回收演算法一共有7個,3個屬於年輕代、三個屬於年老代,G1屬於橫跨年輕代和年老代的演算法。
JVM會從年輕代和年老代各選出一個演算法進行組合,連線表示哪些演算法可以組合使用
二、各個垃圾收集器說明
1、Serial(年輕代)
年輕代收集器,可以和Serial Old、CMS組合使用
採用復制演算法
使用單線程進行垃圾回收,回收時會導致Stop The World,用戶進程停止
client模式年輕代默認演算法
GC日誌關鍵字:DefNew(Default New Generation)
圖示(Serial+Serial Old)
7、G1
G1收集器由於沒有使用過,所以從網上找了一些教程供大家了解
並行與並發
分代收集
空間整合
可預測的停頓
C. JDK1.8版本對於CMS演算法有哪些改進
JDK7.0和JDK6.0有什麼區別?
jdk7是模塊化程序,模塊間的依賴性變小了.jdk的好多功能間有相互依賴性,導致一個配置不對,好多不能用.舉例來說:假設你正使用Logging API(java.util.logging)),Logging需要NIO和JMX,JMX需要JavaBeans, JNDI, RMI和CORBA,JNDI需要java.applet.Applet而且JavaBeans依賴AWT.
JDK7 新特性:
JSR203:JDK中會更多的IO API(「NIO.2」)訪問文件系統與之前的JDK中通過java.io.File訪問文件的方式不同,JDK7將通過java.nio.file包中的類完成。JDK7會使用java.nio.file.Path類來操作任何文件系統中的文件。(這里說的任何文件系統指的是可以使用任何文件存儲方式的文件系統)
示例:
Java7之前
File file = new File(「some_file」);
使用Java7
Path path = Paths.get(「some_file」);
在File類中加入了新的方法toPath(),可以方便的轉換File到Path
Path path = new File(「some_file」).toPath();
Socket通道綁定和配置在JDK7中面向通道的網路編程也得以更新!JDK7中可以直接綁定通道的socket和直接操作socket屬性。JDK7提供了平台socket屬性和指定實現的socket屬性。
JDK7加入了一個新的位元組通道類,SeekableByteChannel
NetworkChannel是面向網路通道編程模塊中的又一個新的超介面。利用它可以方便的綁定通道socket,並且方便設置和獲取socket的屬性。
MulticastChannel介面方便創建IP協議多播。多播實現直接綁定到本地的多播設備。
靈活的非同步I/O可以通過真正的非同步I/O,在不同的線程中運行數以萬計的流操作!JKD7提供了對文件和socket的非同步操作。一些JDK7中的新通道:
AsynchronousFileChannel:非同步文件通道可以完成對文件的非同步讀寫操作。
AsynchronouseSocketChannel:Socket中的一個簡單非同步通道,方法是非同步的並且支持超時。
:非同步的ServerSocket
AsynchronousDatagramChannel:基於數據包的非同步socket
JSR292:Java平台中的動態編程語言Da Vinci Machine項目(JSR292)的主旨是擴展JVM支持除Java以外的其它編程語言,尤其是對動態編程語言的支持。所支持的語言必須和Java一樣不收到歧視並共同存在。JSR334:Java語言的一些改進OpenJDK項目的創造(JSR334)的主旨是對Java語言進行一些小的改進來提高每天的Java開發人員的工作。這些改進包括:
Switch語句允許使用String類型
支持二進制常量和數字常量中可以使用下劃線
使用一個catch語言來處理多種異常類型
對通用類型實例的創建提供類型推理
Try-with-resources語句來自動關閉資源
JSR119:Java編譯器APIJSR199是在JDK6中加入的,主要用來提供調用Java編譯器的API。除了提供javac的命令行工具,JSR199提供Java編譯器到程序交互的能力。Java編譯器API要達到三個目標:
對編譯器和其它工具的調用
對結構化的編譯信息進行訪問
對文件輸入輸出定製化處理的能力
JSR206:Java XML處理的API (JAXP)JSR206即Java API for XML Processing(JAXP),是Java處理XML文檔的一個與實現無關,靈活的API。
JAXP1.3的主要特性包括:
DOM3
內建通過XML Schema進行文檔校驗的處理器
對XML Schema中的數據類型的實現,在javax.xml.datatype包中。
XSLTC,最快的轉換器,也是XSLT處理中的默認引擎。
提供對XInclude的實現。這將會方便我們使用文本和其它已有的XML來創建新的文檔,這樣可以對文檔片段進行重用。
JDK7中會包含JAXP1.3,這個是JAXP的最新實現。
綁定技術(JAXB)JSR222即Java Architecture for XML Binding(JAXB)。JAXB的目的是便於Java程序進行Java類到XML文檔的映射。
JAXB2的主要特性:
支持全部的W3C XML Schema特性。(JAXB1.0說明了對於W3C XML Schema中某些特性的不支持)
支持綁定Java到XML文檔,通過添加javax.xml.bind.annotation包來控制綁定。
大量減少了對於schema衍生出來的類。
通過JAXP1.3的校驗API來提供額外的校驗能力。
JDK7中將包括JAXB2.2
JSR224:基於XML的Web服務API(JAX-WS)JSR224即Java API for XML-based Web Services(JAX-WS),是一個基於Annotation標注的編程模型,主要針對Web Service應用和客戶端開發。
JAX-WS2的主要特性包括:
對JAXB2.1 API的支持(JSR222)
對Web Services Addressing 1.0的支持
EndpointReference(EPR)的API:創建(BindingProvider.getEndpointReference(),Endpoint.getEndpointReference(),MessageContext.getEndpointReference())
事務處理(使用JAXB2.1綁定W3C EPR到W3CEndpointReference類,使用JAXB Marshall/Unmarshall W3CendpointReference類)
提供友好的API來啟用和停止某些特性,例如MTOM特性和Addressing特性
JDK7將包含JAX-WS2.2
可插拔的Annotation處理APIJSR269即Pluggable Annotation-Processing API
從JDK5開始,Annotation標注就成了強大的機制用來標注我們的類、屬性和方法。通常Annotation標注是在創建階段或者運行階段進行處理的,並獲取語義結果。JSR269主要用來定義一套API,允許通過可插拔的API來進行標注處理器的創建。
規范包括一部分的API用來對Java編程語言進行構建,還有就對標注處理器聲明和控制運行的部分。
有了程序中的Annotation標注,就需要有標注處理器框架來反射程序的結構。
Annotation處理器會指定他們處理的標注並且更多的處理器可以合作運行。
標注處理器和程序結構的API可以在構建階段訪問。
小的改進java.util.Objects提供了一套9個靜態方法。其中兩個方法用來檢測當前對象是null還是非null。兩個方法用來提供生成toString()字元串同時支持null對象。兩個用來處理hash的方法。兩個方法用來處理equals。最後一個compare方法用來進行比較。Swing JLayer組件JXLayer是一個組件裝飾器,提供了用來裝飾多個組合組件的方式,並且可以捕獲所有滑鼠、鍵盤和FocusEvent的事件,並針對所有的XLayer子組件。這個組件只會對public swing的api起作用,對全局設置沒有作用,例如對EventQueue或者RepaintManager。(除了這些,Swing還將在JDK7中提供JXDatePicker和CSS方式樣式)並發和集合APIJSR166,並發和集合API提供了靈活的非同步處理,並發HashMap,傳輸隊列和輕量級的fork/join框架以及本地線程方式的偽隨機數生成器。類載入器體系結構類載入器已經升級到了可以在無等級類載入器拓撲中避免死鎖。JDK7中包含了一個對於多線程自定義類載入器的增強實現,名字為具有並行能力的類載入器。使用平行能力的類載入器載入class,會同步到類載入器和類名。Locale類的改進Java Locale避免由於小的變化導致數據丟失。除此,Locale應該提供更多的特性,例如IETF BCP 47和UTR 35(CLDR/LDML)。分離用戶Locale和用戶介面LocaleJDK7分離了UI語言的locale和格式化locale,這個已經在Vista之後的windows系統中實現了。嚴格的類文件檢測通過JavaSE6的規范,version51(SE7)的類文件和之後的版本必須通過類型檢測來檢驗。對於老的推理驗證VM不可以宕掉Elliptic-Curve
Cryptography (ECC)橢圓曲線加密
從JDK7開始,Java提供對標準的ECC演算法的靈活實現(基於橢圓曲線的公鑰加密演算法)Swing中的Nimbus外觀Nimbus是JDS(Java Desktop System)中的新外觀。這個也是Solaris11的GTK主題Java2D中的XRender PipelineJDK7中加入了基於X11 XRender擴展的Java2D圖形管道。這將提供更多的對於當前先進的GPUs訪問的功能。TLS1.2TLS (Transport Layer Security)是一個用在Internet上的數據傳輸安全協議,用來避免監聽、引誘和消息偽造。TLS的主要目的是提供兩個應用間通信的隱私和數據完整。TLS是RFC5246標准,在JDK7中提供1.2JDBC4.0/4.1JDBC4.1特性只在JDK7或者更高版本中存在。JDBC4.1隻是對JDBC4.0進行較小的改動。關於一些JDBC4.0/4.1的特性:
數據源—Derby包括了對於javax.sql.DataSource的新的實現
JDBC驅動自動載入—應用不必在通過Class.forName()方法來載入資料庫驅動了。取而代之的是DriverManager會根據應用請求連接的情況,自動查找到合適的JDBC驅動。
包裝—這是JDBC4.0中的新的概念,主要是通過這種機制可以讓應用獲取的廠商提供的標准JDBC對象實現,例如Connections,Statements和ResultSets。
Statement事件—連接池可以監聽Statement的關閉和錯誤時間。addStatementEventListener和removeStatementEventListener被加入到了javax.sql.PooledConnection
JDK7提供了JDBC4.1全部的支持
透明窗體和異形窗體為了6u10版本的圖形處理,JDK提供了透明效果的支持(簡單透明和像素透明)並且提供了對於異形窗體的支持(可以將窗體設置成任意形狀),輕重混合並且增強了AWT安全警告。透明效果和異形窗體是通過com.sun.awt.AWTUtilities類實現的。Unicode6.0Unicode6.0提供了諸如2.088字元集、對已經存在字元集的屬性改進、格式化改進以及新的屬性和數據文件。
JDK7已經更新到對Unicode6.0的支持。
要來關閉URLClassLoader的方法
對JMX代理和MBeans的改進
通過URLClassLoader,應用可以通過URL搜索路徑來載入類和資源。JKD7提供了close()新方法來幫助URLClassLoader清理資源。
這個改進來至於JRockit,可以方便連接平台。MBean伺服器可以通過防火牆提供一套MBeans,這些暴露了VM中的一些內部操作的信息
新的垃圾回收器JDK7提供了新的垃圾回收器,針對目前的CMS垃圾回收器,這將會讓垃圾回收器有更少的停頓時間和更高的語言效果。改進的JSRJSR901:Java Language Specification(JLS)Java語言計劃
JSR901包括了從第一版Java規范到現在為止的所有的變化、說明和補充。Java語言通過JLS規范。
對於JLS的改變通過JSR901進行管理
JDK7將會包括最新的JSR901
JSR924:JVM平台規范
JSR924目的是維護Java虛擬機規范的變化,其中第二版是為了J2SE1.5的。
Java SE API
JavaSE APIs保持著對例行維護和小范圍改進的加入計劃的記錄
延期到JDK8或者之後的規范
JSR294:Java語言和虛擬機對模塊編程技術的支持—當前JSR主要的目的是提供在編譯期和運行期的模塊編程支持
JSR308:對於Java類型的Annotation注釋—這將是對於當前注釋符號系統的擴展,將允許我們在類型中出現注釋符號。
JSR296:Swing應用框架—主旨是消除Swing編程中的模板代碼並且提供Swing程序更加簡單的結構。
模塊化—提供一個明確的、簡單的、低級別的模塊系統,主要目的是將JDK模塊化。
JSR TBD:Lambda項目—Lambda表達式(通俗的也稱為「閉包「)和對Java編程語言的保護方法
JSR TBD:對於集合支持的語言—常量表達式對於lists、sets和maps的迭代以及通過索引符號對lists和maps的訪問。
Swing JDatePicker組件—添加SwingLabs JXDatePicker組件到平台。
D. java虛擬機常見的幾種垃圾收集演算法
1、垃圾收集器概述
垃圾收集器是垃圾回收演算法(標記-清除演算法、復制演算法、標記-整理演算法、火車演算法)的具體實現,不同商家、不同版本的JVM所提供的垃圾收集器可能會有很在差別,本文主要介紹HotSpot虛擬機中的垃圾收集器。
1-1、垃圾收集器組合
JDK7/8後,HotSpot虛擬機所有收集器及組合(連線),如下圖:
(A)、圖中展示了7種不同分代的收集器:
Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1;
(B)、而它們所處區域,則表明其是屬於新生代收集器還是老年代收集器:
新生代收集器:Serial、ParNew、Parallel Scavenge;
老年代收集器:Serial Old、Parallel Old、CMS;
整堆收集器:G1;
(C)、兩個收集器間有連線,表明它們可以搭配使用:
Serial/Serial Old、Serial/CMS、ParNew/Serial Old、ParNew/CMS、Parallel Scavenge/Serial Old、Parallel Scavenge/Parallel Old、G1;
(D)、其中Serial Old作為CMS出現"Concurrent Mode Failure"失敗的後備預案(後面介紹);
1-2、並發垃圾收集和並行垃圾收集的區別
(A)、並行(Parallel)
指多條垃圾收集線程並行工作,但此時用戶線程仍然處於等待狀態;
如ParNew、Parallel Scavenge、Parallel Old;
(B)、並發(Concurrent)
指用戶線程與垃圾收集線程同時執行(但不一定是並行的,可能會交替執行);
用戶程序在繼續運行,而垃圾收集程序線程運行於另一個CPU上;
如CMS、G1(也有並行);
1-3、Minor GC和Full GC的區別
(A)、Minor GC
又稱新生代GC,指發生在新生代的垃圾收集動作;
因為Java對象大多是朝生夕滅,所以Minor GC非常頻繁,一般回收速度也比較快;
(B)、Full GC
又稱Major GC或老年代GC,指發生在老年代的GC;
出現Full GC經常會伴隨至少一次的Minor GC(不是絕對,Parallel Sacvenge收集器就可以選擇設置Major GC策略);
Major GC速度一般比Minor GC慢10倍以上;
E. 以下哪些jvm的垃圾回收方式採用的是復制演算法回收
1.Serial New/Serial Old
Serial/Serial Old收集器是最基本最古老的收集器,它是一個單線程收集器,並且在它進行垃圾收集時,必須暫停所有用戶線程。Serial New收集器是針對新生代的收集器,採用的是Copying演算法,Serial Old收集器是針對老年代的收集器,採用的是Mark-Compact演算法。它的優點是實現簡單高效,但是缺點是會給用戶帶來停頓。
2.Parallel New
Parallel New收集器是Serial收集器的多線程版本(參照Serial New),使用多個線程進行垃圾收集。
3.Parallel Scavenge
Parallel Scavenge收集器是一個新生代的多線程收集器(並行收集器),它在回收期間不需要暫停其他用戶線程,其採用的是Copying演算法,該收集器與前兩個收集器有所不同,它主要是為了達到一個可控的吞吐量。
4.Parallel Old
Parallel Old是Parallel Scavenge收集器的老年代版本(並行收集器),使用多線程和Mark-Compact演算法。
5.CMS
CMS(Current Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器,它是一種並發收集器,採用的是Mark-Sweep演算法。
6.G1
G1收集器是當今收集器技術發展最前沿的成果,它是一款面向服務端應用的收集器,它能充分利用多CPU、多核環境。因此它是一款並行與並發收集器,並且它能建立可預測的停頓時間模型。
F. cms垃圾回收演算法在gc過程中哪幾個階段會暫停應用縣城
中間調整過幾次,先搞了幾台機器做了驗證,後來逐步推廣的。
1、調大heap區,由原來的4g,調整到5g,young區的大小不變,還是2g,這時候old區就由2g變為3g了(這樣保證old區有足夠的空間);
2、設置-XX:UseCMSInitiatingOccupancyOnly,其實這個不關這個問題,只是發現半夜CMS進行的有點頻繁,就禁止掉了悲觀策略;
3、設置CMS區回收的比例,從80%調整到75%,讓old區盡早的進行,有足夠的空間剩餘;
為什麼要有GC(垃圾回收)?
JVM通過GC來回收堆和方法區中的內存,GC的基本原理就是找到程序中不再被使用的對象,然後回收掉這些對象佔用的內存。
主要的收集器有哪些?
引用計數器和跟蹤計數器兩種。
引用計數器記錄對象是否被引用,當計數器為零時,說明對象已經不再被使用,可以進行回收。java中的對象有復雜的引用關系,不是很適合引用計數器,所以sun jdk中並沒有實現這種GC方式。
跟蹤收集器,全局記錄數據的引用狀態,基於一定的條件觸發。執行的時候,從根集合開始掃描對象的引用關系,主要有復制(ing)、標記-清除(Mark-Sweep)、標記-壓縮(Mark-Compact)那種演算法。
G. cms垃圾回收演算法在gc過程哪幾個階段會暫停應用線程
在正式復回答這個問題之前,先制簡單說說Java運行時內存區,劃分為線程私有區和線程共享區:(1)線程私有區:程序計數器,記錄正在執行的虛擬機位元組碼的地址;虛擬機棧:方法執行的內存區,每個方法執行時會在虛擬機棧中創建棧幀;本地方法棧:虛擬機的Native方法執行的內存區;(2)線程共享區:Java堆:對象分配內存的區域,這是垃圾回收的主戰場;方法區:存放類信息、常量、靜態變
H. majorgc觸發條件
Major GC通常是跟full GC是等價的,收集整個GC堆。但因為HotSpot VM發展了這么多年,外界對各種名詞的解讀已經完全混亂了,當有人說「major GC」的時候一定要問清楚他想要指的是上面的full GC還是old gen。
最簡單的分代式GC策略,按HotSpot VM的serial GC的實現來看,觸發條件是:
young GC:當young gen中的eden區分配滿的時候觸發。注意young GC中有部分存活對象會晉升到old gen,所以young GC後old gen的佔用量通常會有所升高。
full GC:當准備要觸發一次young GC時,如果發現統計數據說之前young GC的平均晉升大小比目前old gen剩餘的空間大,則不會觸發young GC而是轉為觸發full GC(因為HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都會同時收集整個GC堆,包括young gen,所以不需要事先觸發一次單獨的young GC);或者,如果有perm gen的話,要在perm gen分配空間但已經沒有足夠空間時,也要觸發一次full GC;或者System.gc()、heap mp帶GC,默認也是觸發full GC。
HotSpot VM里其它非並發GC的觸發條件復雜一些,不過大致的原理與上面說的其實一樣。
當然也總有例外。Parallel Scavenge(-XX:+UseParallelGC)框架下,默認是在要觸發full GC前先執行一次young GC,並且兩次GC之間能讓應用程序稍微運行一小下,以期降低full GC的暫停時間(因為young GC會盡量清理了young gen的死對象,減少了full GC的工作量)。這是HotSpot VM里的奇葩嗯。
並發GC的觸發條件就不太一樣。以CMS GC為例,它主要是定時去檢查old gen的使用量,當使用量超過了觸發比例就會啟動一次CMS GC,對old gen做並發收集。
I. java垃圾是怎麼回收的,回收演算法
Java ,C#語言與C/C++語言一個很大的區別是java與C#具有自動垃圾回收機制。C++程序員經常需要絞盡腦汁的分析哪裡出現了內存泄漏。而在java,C#中,雖然有時也會出現內存泄漏,但大部分情況下程序員不需要考慮對象或者數據何時需要被銷毀。因此程序員不會因為錯誤的釋放內存而導致程序崩潰。垃圾回收的缺點是加大了程序的負擔,有可能影響程序的性能。
1.垃圾收集器的主要功能有
(1) 定期發現那些對象不再被引用,並把這些對象占據的堆空間釋放出來。
(2) 類似於操作系統的內存管理,垃圾收集器還需要處理由於對象動態生成與銷毀產生的堆碎塊,以便更有效的利用虛擬機內存。
2.區分活動對象與垃圾的演算法
(1)引用計數法
堆中每一個對象都有一個引用計數。當新創建一個對象,或者有變數被賦值為這個對象的引用,則這個對象的引用計數加1;當一個對象的引用超過生存期或者被設置一個新的值時,這個對象的引用計數減1。當對象的引用計數變為0時,就可以被當作垃圾收集。
這種方法的好處是垃圾收集較快,適用於實時環境。缺點是這種方法無法監測出循環引用。例如對象A引用對象B,對象B也引用對象A,則這兩個對象可能無法被垃圾收集器收集。因此這種方法是垃圾收集的早期策略,現在很少使用。
(2)跟蹤法
這種方法把每個對象看作圖中一個節點,對象之間的引用關系為圖中各節點的鄰接關系。垃圾收集器從一個或數個根結點遍歷對象圖,如果有些對象節點永遠無法到達,則這個對象可以被當作垃圾回收。
容易發現,這種方法可以檢測出循環引用,避免了引用計數法的缺點,較為常用。
3.常用垃圾回收機制
(1)標記-清除收集器
這種收集器首先遍歷對象圖並標記可到達的對象,然後掃描堆棧以尋找未標記對象並釋放它們的內存。這種收集器一般使用單線程工作並停止其他操作。
(2)標記-壓縮收集器
有時也叫標記-清除-壓縮收集器,與標記-清除收集器有相同的標記階段。在第二階段,則把標記對象復制到堆棧的新域中以便壓縮堆棧。這種收集器也停止其他操作。
(3)復制收集器
這種收集器將堆棧分為兩個域,常稱為半空間。每次僅使用一半的空間,虛擬機生成的新對象則放在另一半空間中。垃圾回收器運行時,它把可到達對象復制到另一半空間,沒有被復制的的對象都是不可達對象,可以被回收。這種方法適用於短生存期的對象,持續復制長生存期的對象由於多次拷貝,導致效率降低。缺點是只有一半的虛擬機空間得到使用。
(4)增量收集器
增量收集器把堆棧分為多個域,每次僅從一個域收集垃圾。這會造成較小的應用程序中斷。
(5)分代收集器
這種收集器把堆棧分為兩個或多個域,用以存放不同壽命的對象。虛擬機生成的新對象一般放在其中的某個域中。過一段時間,繼續存在的對象將獲得使用期並轉入更長壽命的域中。分代收集器對不同的域使用不同的演算法以優化性能。這樣可以減少復制對象的時間。
(6)並發收集器
並發收集器與應用程序同時運行。這些收集器在某點上(比如壓縮時)一般都不得不停止其他操作以完成特定的任務,但是因為其他應用程序可進行其他的後台操作,所以中斷其他處理的實際時間大大降低。
(7)並行收集器
並行收集器使用某種傳統的演算法並使用多線程並行的執行它們的工作。在多CPU機器上使用多線程技術可以顯著的提高java應用程序的可擴展性。
(8)自適應收集器
根據程序運行狀況以及堆的使用狀況,自動選一種合適的垃圾回收演算法。這樣可以不局限與一種垃圾回收演算法。
4. 火車演算法
垃圾收集演算法一個很大的缺點就是難以控制垃圾回收所佔用的CPU時間,以及何時需要進行垃圾回收。火車演算法是分代收集器所用的演算法,目的是在成熟對象空間中提供限定時間的漸進收集。目前應用於SUN公司的Hotspot虛擬機上。
在火車演算法中,內存被分為塊,多個塊組成一個集合。為了形象化,一節車廂代表一個塊,一列火車代表一個集合,見圖一
注意每個車廂大小相等,但每個火車包含的車廂數不一定相等。垃圾收集以車廂為單位,收集順序依次為1.1,1.2,1.3,1.4,2.1,2.2,2.3,3.1,3.2,3.3。這個順序也是塊被創建的先後順序。
垃圾收集器先從塊1.1開始掃描直到1.4,如果火車1四個塊中的所有對象沒有被火車2和火車3的對象引用,而只有火車1內部的對象相互引用,則整個火車1都是垃圾,可以被回收。
如圖二,車廂1.1中有對象A和對象B,1.3中有對象C,1.4中有對象D,車廂2.2中有對象E,車廂3.3中有對象F。在火車1中,對象C引用對象A,對象B引用對象D,可見,火車2和火車3沒有引用火車1的對象,則整個火車1都是垃圾。
如果火車1中有對象被其它火車引用,見圖三,掃描車廂1.1時發現對象A被火車2中的E引用,則將對象A從車廂1.1轉移到車廂2.2,然後掃描A引用的對象D,把D也轉移到車廂2.2,然後掃描D,看D是否引用其它對象,如果引用了其它對象則也要轉移,依次類推。掃描完火車1的所有對象後,剩下的沒有轉移的對象都是垃圾,可以把整個火車1都作為垃圾回收。注意如果在轉移時,如果車廂2.2空間滿了,則要在火車2末尾開辟新的車廂2.4,將新轉移的對象都放到2.4,即火車的尾部)
補充說明:垃圾回收器一次只掃描一個車廂。圖三中的對象B與C並不是立即被回收,而是先會被轉移到火車1的尾部車廂。即掃描完1.1後,B被轉移到火車1尾部,掃描完1.3後,C被轉移到車尾。等垃圾收集器掃描到火車1尾部時,如果仍然沒有外部對象引用它們,則B和C會被收集。
火車演算法最大的好處是它可以保證大的循環結構可以被完全收集,因為成為垃圾的循環結構中的對象,無論多大,都會被移入同一列火車,最終一起被收集。還有一個好處是這種演算法在大多數情況下可以保證一次垃圾收集所耗時間在一定限度之內,因為一次垃圾回收只收集一個車廂,而車廂的大小是有限度的。