JVM 默認啓動參數中,DisableExplicitGC 爲 false,ExplicitGCInvokesConcurrent 爲 false,對於大多數 GC (除了 ZGC 的其餘 GC,包括 CMS,G1,Shenandoah GC 等等),都是會進行 FullGC 的,而且都是同步 GC 的,其中底層的原理會在另外一篇詳細分析,咱們先來搞清楚爲何要留這樣一個接口呢?java
JVM 的內存,不止堆內存,還有其餘不少塊,經過 Native Memory Tracking 能夠看到:編程
Native Memory Tracking: Total: reserved=6308603KB, committed=4822083KB - Java Heap (reserved=4194304KB, committed=4194304KB) (mmap: reserved=4194304KB, committed=4194304KB) - Class (reserved=1161041KB, committed=126673KB) (classes #21662) ( instance classes #20542, array classes #1120) (malloc=3921KB #64030) (mmap: reserved=1157120KB, committed=122752KB) ( Metadata: ) ( reserved=108544KB, committed=107520KB) ( used=105411KB) ( free=2109KB) ( waste=0KB =0.00%) ( Class space:) ( reserved=1048576KB, committed=15232KB) ( used=13918KB) ( free=1314KB) ( waste=0KB =0.00%) - Thread (reserved=355251KB, committed=86023KB) (thread #673) (stack: reserved=353372KB, committed=84144KB) (malloc=1090KB #4039) (arena=789KB #1344) - Code (reserved=252395KB, committed=69471KB) (malloc=4707KB #17917) (mmap: reserved=247688KB, committed=64764KB) - GC (reserved=199635KB, committed=199635KB) (malloc=11079KB #29639) (mmap: reserved=188556KB, committed=188556KB) - Compiler (reserved=2605KB, committed=2605KB) (malloc=2474KB #2357) (arena=131KB #5) - Internal (reserved=3643KB, committed=3643KB) (malloc=3611KB #8683) (mmap: reserved=32KB, committed=32KB) - Other (reserved=67891KB, committed=67891KB) (malloc=67891KB #2859) - Symbol (reserved=26220KB, committed=26220KB) (malloc=22664KB #292684) (arena=3556KB #1) - Native Memory Tracking (reserved=7616KB, committed=7616KB) (malloc=585KB #8238) (tracking overhead=7031KB) - Arena Chunk (reserved=10911KB, committed=10911KB) (malloc=10911KB) - Tracing (reserved=25937KB, committed=25937KB) (malloc=25937KB #8666) - Logging (reserved=5KB, committed=5KB) (malloc=5KB #196) - Arguments (reserved=18KB, committed=18KB) (malloc=18KB #486) - Module (reserved=532KB, committed=532KB) (malloc=532KB #3579) - Synchronizer (reserved=591KB, committed=591KB) (malloc=591KB #4777) - Safepoint (reserved=8KB, committed=8KB) (mmap: reserved=8KB, committed=8KB)
-Xmx
限制的最大堆大小的內存。-XX:MaxMetaspaceSize
限制最大大小,另外是 class space,被-XX:CompressedClassSpaceSize
限制最大大小-Xss
限制,可是總大小沒有限制。-XX:ReservedCodeCacheSize
限制-XX:StringTableSize
個數限制,總內存大小不受限制除了 Native Memory Tracking 記錄的內存使用,還有兩種內存 Native Memory Tracking 沒有記錄,那就是:微信
針對除了堆內存之外,其餘的內存,有些也是須要 GC 的。例如:MetaSpace,CodeCache,Direct Buffer,MMap Buffer 等等。早期在 Java 8 以前的 JVM,對於這些內存回收的機制並不完善,不少狀況下都須要 FullGC 掃描整個堆才能肯定這些區域中哪些內存能夠回收。框架
有一些框架,大量使用並管理了這些堆外空間。例如 netty 使用了 Direct Buffer,Kafka 和 RocketMQ 使用了 Direct Buffer 和 MMap Buffer。他們都是提早從系統申請好一塊內存,以後管理起來並使用。在空間不足時,繼續向系統申請,而且也會有縮容。例如 netty,在使用的 Direct Buffer 達到-XX:MaxDirectMemorySize
的限制以後,則會先嚐試將不可達的Reference對象加入Reference鏈表中,依賴Reference的內部守護線程觸發能夠被回收DirectByteBuffer關聯的Cleaner的run()方法。若是內存仍是不足, 則執行System.gc()
,指望觸發full gc
,來回收堆內存中的DirectByteBuffer
對象來觸發堆外內存回收,若是仍是超過限制,則拋出java.lang.OutOfMemoryError
.ide
對於 WeakReference,只要發生 GC,不管是 Young GC 仍是 FullGC 就會被回收。SoftReference 只有在 FullGC 的時候纔會被回收。當咱們程序想主動對於這些引用進行回收的時候,須要能觸發 GC 的方法,這就用到了System.gc()
。學習
有些時候,咱們爲了測試,學習 JVM 的某些機制,須要讓 JVM 作一次 GC 以後開始,這也會用到System.gc()
。測試
微信搜索「個人編程喵」關注公衆號,每日一刷,輕鬆提高技術,斬獲各類offer:優化