本文基于 Java 17-ea,但是相关设计在 Java 11 之后是大致一样的
我们经常在面试中询问 System.gc() 究竟会不会 立刻 触发 Full GC ,网上也有很多人给出了答案,但是这些答案都有些过时了。本文基于最新的信息 Java 的下一个即将发布的 LTS 版本 Java 17(ea)的源代码,深入解析 System.gc() 背后的故事。
为什么需要 System.gc()
1. 使用并管理堆外内存的框架,需要 Full GC 的机制触发堆外内存回收
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)
(mall