java中的垃圾收集器
Garbage collection in java is one of the advance topic. Java GC knowledge helps us in fine tuning our application runtime performance.
Java中的垃圾回收是高級主題之一。 Java GC知識有助于我們微調應用程序的運行時性能。
Automatic Garbage collection is a process of looking at the Heap memory, identifying(also known as “marking”) the unreachable objects, and destroying them with compaction.
自動垃圾收集是查看堆內存,識別(也稱為“標記”)不可達對象并通過壓縮將其破壞的過程。
An issue with this approach is that, as the number of objects increases, the Garbage Collection time keeps on increasing, as it needs to go through the entire list of objects, looking for the unreachable object.
這種方法的問題在于,隨著對象數量的增加,垃圾收集時間會不斷增加,因為它需要遍歷對象的整個列表,以尋找不可達的對象。
However, the empirical analysis of applications shows that most of the objects are short-lived.
但是,對應用程序的經驗分析表明,大多數對象都是短暫的。
This behavior was used to improve the performance of JVM, and the adopted methodology is commonly called Generational Garbage Collection. In this method, the Heap space is divided into generations like Young Generation, Old or Tenured Generation, and Permanent Generation.
此行為用于提高JVM的性能,并且采用的方法通常稱為Generational Garbage Collection。 在這種方法中,堆空間被分為幾代,如年輕一代,老一代或終身一代以及永久一代。
The Young generation heap space is the new where all the new Objects are created. Once it gets filled up, minor garbage collection (also known as, Minor GC) takes place. Which means, all the dead objects from this generation are destroyed This process is quick because as we can see from the graph, most of them would be dead. The surviving objects in young generation are aged and eventually moves to the older generations.
Young一代堆空間是創建所有新對象的新空間。 一旦被填滿,就會進行次要垃圾收集(也稱為Minor GC)。 這意味著,這一代中的所有死亡對象都被銷毀了。此過程之所以Swift,是因為從圖中可以看出,大多數對象都是死亡的。 年輕一代中幸存的物體已經老化,并最終移交給了老一代。
The Old Generation is used to store long surviving objects. Typically, a threshold is set for young generation object and when that age is met, the object gets moved to the old generation. Eventually, the old generation needs to be collected. This event is called a Major GC (major garbage collection). Often it is much slower because it involves all live objects.
Also, there is Full GC, which means cleaning the entire Heap – both Young and older generation spaces.
老一代用于存儲尚存的物體。 通常,為年輕一代對象設置一個閾值,并且當達到該年齡時,該對象將移至老一代。 最終,需要收集舊的一代。 此事件稱為主要GC(主要垃圾回收)。 通常,它要慢得多,因為它涉及所有活動對象。
此外,還有完整的GC,這意味著可以清潔整個堆堆-年輕一代和老一代空間。
Lastly, up to Java 7, there was a Permanent Generation (or Perm Gen), which contained metadata required by the JVM to describe the classes and methods used in the application. It was removed in Java 8.
最后,直到Java 7,都有一個永久代(或Perm Gen),其中包含JVM所需的元數據,用于描述應用程序中使用的類和方法。 在Java 8中已將其刪除。
The JVM actually provides four different garbage collectors, all of them generational. Each one has their own advantages and disadvantages. The choice of which garbage collector to use lies with us and there can be dramatic differences in the throughput and application pauses.
JVM實際上提供了四個不同的垃圾收集器,它們都是世代相傳的。 每個人都有自己的優點和缺點。 使用哪種垃圾收集器的選擇由我們決定,吞吐量和應用程序暫停可能會有很大差異。
All these, split the managed heap into different segments, using the age-old assumptions that most objects in the heap are short-lived and should be recycled quickly.
所有這些都使用古老的假設將托管堆分成不同的段,這些假設是堆中的大多數對象都是短暫的,應該Swift回收。
So, the four types of garbage collectors are:
因此,四種類型的垃圾收集器是:
This is the simplest garbage collector, designed for single threaded systems and small heap size. It freezes all applications while working. Can be turned on using -XX:+UseSerialGC
JVM option.
這是最簡單的垃圾收集器,設計用于單線程系統和較小的堆大小。 它會在工作時凍結所有應用程序。 可以使用-XX:+UseSerialGC
JVM選項打開。
This is JVM’s default collector in JDK 8. As the name suggests, it uses multiple threads to scan through the heap space and perform compaction. A drawback of this collector is that it pauses the application threads while performing minor or full GC.
It is best suited if applications that can handle such pauses, and try to optimize CPU overhead caused by the collector.
這是JVM在JDK 8中的默認收集器。顧名思義,它使用多個線程來掃描堆空間并執行壓縮。 該收集器的一個缺點是在執行次要或完全GC時會暫停應用程序線程。
如果應用程序可以處理此類暫停,并嘗試優化由收集器引起的CPU開銷,則是最適合的。
The CMS collector (“concurrent-mark-sweep”) algorithm uses multiple threads (“concurrent”) to scan through the heap (“mark”) for unused objects that can be recycled (“sweep”).
CMS收集器(“ concurrent-mark-sweep”)算法使用多個線程(“ concurrent”)在堆(“ mark”)中掃描可回收(“ sweep”)未使用的對象。
This collector goes in Stop-The-World(STW) mode in two cases:
-While initializing the initial marking of roots, ie. objects in the old generation that are reachable from thread entry points or static variables
-When the application has changed the state of the heap while the algorithm was running concurrently and forcing it to go back and do some final touches to make sure it has the right objects marked.
在兩種情況下,此收集器進入“世界停止”(STW)模式:
-在初始化根的初始標記時,即 線程入口點或靜態變量可訪問的舊對象
-當應用程序在算法同時運行時更改了堆的狀態,并迫使其返回并進行最后的修改時,請確保已標記了正確的對象。
This collector may face promotion failures. If some objects from young generation are to be moved to the old generation, and the collector did not have enough time to make space in the old generation space, a promotion failure will occur.
In order to prevent this, we may provide more of the heap size to the old generation or provide more background threads to the collector.
該收集器可能會面臨升級失敗。 如果要將年輕一代的某些對象移到老一代,并且收集器沒有足夠的時間在老一代空間中騰出空間,則會發生升級失敗。
為了防止這種情況,我們可能會為舊一代提供更多的堆大小,或者為收集器提供更多的后臺線程。
Last but not the least is the Garbage-First collector, designed for heap sizes greater than 4GB. It divides the heap size into regions spanning from 1MB to 32Mb, based on the heap size.
最后但并非最不重要的是Garbage-First收集器,其設計用于大于4GB的堆大小。 它將根據堆大小將堆大小分為1MB到32Mb的區域。
There is a concurrent global marking phase to determine the liveliness of objects throughout the heap. After the marking phase is complete, G1 knows which regions are mostly empty. It collects unreachable objects from these regions first, which usually yields a large amount of free space. So G1 collects these regions(containing garbage) first, and hence the name Garbage-First. G1 also uses a pause prediction model in order to meet a user-defined pause time target. It selects the number of regions to collect based on the specified pause time target.
有一個并發的全局標記階段來確定整個堆中對象的活動性。 標記階段完成后,G1知道哪些區域大部分為空。 它首先從這些區域收集無法到達的對象,這通常會產生大量的可用空間。 因此,G1首先收集這些區域(包含垃圾),因此名稱為Garbage-First。 為了滿足用戶定義的暫停時間目標,G1還使用了暫停預測模型。 它根據指定的暫停時間目標選擇要收集的區域數。
The G1 garbage collection cycle includes the phases as shown in the figure:
G1垃圾回收周期包括以下各階段:
G1 can be enabled using the –XX:+UseG1GC
flag.
可以使用–XX:+UseG1GC
標志啟用G1。
This strategy reduced the chances of the heap being depleted before the background threads have finished scanning for unreachable objects. Also, it compacts the heap on-the-go, which the CMS collector can do only in STW mode.
此策略減少了在后臺線程完成對不可達對象的掃描之前耗盡堆的機會。 此外,它還可以在移動時壓縮堆,CMS收集器只能在STW模式下執行此操作。
In Java 8 a beautiful optimization is provided with G1 collector, called string deduplication. As we know the character arrays that represent our strings occupies much of our heap space. A new optimization has been made that enables the G1 collector to identify strings which are duplicated more than once across our heap and modify them to point to the same internal char[] array, to avoid multiple copies of the same string residing in the heap unnecessarily. We can use the -XX:+UseStringDeduplication
JVM argument to enable this optimization.
在Java 8中,G1收集器提供了一個漂亮的優化,稱為字符串重復數據刪除 。 眾所周知,代表字符串的字符數組占用了我們很多的堆空間。 進行了新的優化,使G1收集器可以識別在我們的堆中重復多次的字符串,并對其進行修改以指向同一內部char []數組,以避免不必要地將同一字符串的多個副本駐留在堆中。 我們可以使用-XX:+UseStringDeduplication
JVM參數來啟用此優化。
G1 is the default garbage collector in JDK 9.
G1是JDK 9中的默認垃圾收集器。
As mentioned earlier, the Permanent Generation space was removed since Java 8. So now, the JDK 8 HotSpot JVM uses the native memory for the representation of class metadata which is called Metaspace.
如前所述,自Java 8開始就刪除了永久生成空間。因此,現在,JDK 8 HotSpot JVM使用本機內存來表示類元數據,即元空間。
Most of the allocations for the class metadata are made out of the native memory. Also, there is a new flag MaxMetaspaceSize, to limit the amount of memory used for class metadata. If we do not specify the value for this, the Metaspace re-sizes at runtime as per the demand of the running application.
類元數據的大多數分配都是在本機內存中進行的。 另外,還有一個新的標志MaxMetaspaceSize,以限制用于類元數據的內存量。 如果我們沒有為此指定值,則Metaspace將在運行時根據正在運行的應用程序的需求重新調整大小。
Metaspace garbage collection is triggered when the class metadata usage reaches MaxMetaspaceSize limit. Excessive Metaspace garbage collection may be a symptom of classes, classloaders memory leak or inadequate sizing for our application.
當類元數據使用量達到MaxMetaspaceSize限制時,將觸發元空間垃圾回收。 過多的Metaspace垃圾回收可能是類的癥狀,類加載器內存泄漏或應用程序大小不足。
That’s it for the Garbage Collection in java. I hope you got the understanding about different garbage collectors we have in java.
Java垃圾收集就這樣了。 希望您對Java中的不同垃圾收集器有所了解。
References: Oracle Documentation, G1 GC.
參考: Oracle文檔 , G1 GC 。
翻譯自: https://www.journaldev.com/16659/garbage-collection-in-java
java中的垃圾收集器
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态