2021-2-26:为什么需要 System.gc() ?
JVM 默认启动参数中,DisableExplicitGC 为 false,ExplicitGCInvokesConcurrent 为 false,对于大多数 GC (除了 ZGC 的其他 GC,包括 CMS,G1,Shenandoah GC 等等),都是会进行 FullGC 的,并且都是同步 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)
(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)
- Java Heap: 堆内存,即
-Xmx
限制的最大堆大小的内存。 - Class:加载的类与方法信息,其实就是 metaspace,包含两部分: 一是 metadata,被
-XX:MaxMetaspaceSize
限制最大大小,另外是 class space,被-XX:CompressedClassSpaceSize
限制最大大小 - Thread:线程与线程栈占用内存,每个线程栈占用大小受
-Xss
限制,但是总大小没有限制。 - Code:JIT 即时编译后(C1 C2 编译器优化)的代码占用内存,受
-XX:ReservedCodeCacheSize
限制 - GC:垃圾回收占用内存,例如垃圾回收需要的 CardTable,标记数,区域划分记录,还有标记 GC Root 等等,都需要内存。这个不受限制,一般不会很大的。
- Compiler:C1 C2 编译器本身的代码和标记占用的内存,这个不受限制,一般不会很大的
- Internal:命令行解析,JVMTI 使用的内存,这个不受限制,一般不会很大的
- Symbol: 常量池占用的大小,字符串常量池受
-XX:StringTableSize
个数限制,总内存大小不受限制 - Native Memory Tracking:内存采集本身占用的内存大小,如果没有打开采集(那就看不到这个了,哈哈),就不会占用,这个不受限制,一般不会很大的
- Arena Chunk:所有通过 arena 方式分配的内存,这个不受限制,一般不会很大的
- Tracing:所有采集占用的内存,如果开启了 JFR 则主要是 JFR 占用的内存。这个不受限制,一般不会很大的
- Logging,Arguments,Module,Synchronizer,Safepoint,Other,这些一般我们不会关心。
除了 Native Memory Tracking 记录的内存使用,还有两种内存 Native Memory Tracking 没有记录,那就是:
- Direct Buffer:直接内存
- MMap Buffer:文件映射内存
针对除了堆内存以外,其他的内存,有些也是需要 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
.
2. 使用了 WeakReference, SoftReference 的程序,需要相应的 GC 回收。
对于 WeakReference,只要发生 GC,无论是 Young GC 还是 FullGC 就会被回收。SoftReference 只有在 FullGC 的时候才会被回收。当我们程序想主动对于这些引用进行回收的时候,需要能触发 GC 的方法,这就用到了System.gc()
。
3. 测试,学习 JVM 机制的时候
有些时候,我们为了测试,学习 JVM 的某些机制,需要让 JVM 做一次 GC 之后开始,这也会用到System.gc()
。
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:
2021-2-26:为什么需要 System.gc() ?的更多相关文章
- Java的垃圾回收机制:强制回收System.gc() Runtime.getTime().gc()
垃圾回收 当引用类型的实体,如对象.数组等不再被任何变量引用的时候.这块占用的内存就成为了垃圾.JVM会根据自己的策略决定是回收内存 注意: 垃圾回收只回收内存中的对象,无法回收物理资源(数据库连接, ...
- 实战Java虚拟机之四:提升性能,禁用System.gc() ?
今天开始实战Java虚拟机之四:"禁用System.gc()". 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟 ...
- java: system.gc()和垃圾回收机制finalize
System.gc()和垃圾回收机制前的收尾方法:finalize(收尾机制) 程序退出时,为每个对象调用一次finalize方法,垃圾回收前的收尾方法 System.gc() 垃圾回收方法 clas ...
- System.gc()与Object.finalize()的区别
finalize()是由JVM自动调用的,你可以用System.gc(),但JVM不一定会立刻执行,JVM感觉内存空间有限时,才会开始执行finalize(),至于新的对象创建个数和被收集个数不同是因 ...
- finalize与System.gc()
finalize Finalize是Object类的一个方法,可以用来被重写 finalize的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只 ...
- System.gc
Java中的内存分配是随着new一个新的对象来实现的,这个很简单,而且也还是有一些可以“改进”内存回收的机制的,其中最显眼的就是这个System.gc()函数. 乍一看这个函数似乎是可以进行垃圾回收的 ...
- 由dubbo服务禁用system.gc而引起的思考
我一直都有一个疑问,丰巢业务服务的生产环境jvm参数设置是禁止system.gc的,也就是开启设置:-XX:+DisableExplicitGC,但是生产环境却从来没有出现过堆外内存溢出的情况.说明一 ...
- (转)调用System.gc没有立即执行的解决方法
调用System.gc没有立即执行的解决方法 查看源码 当我们调用System.gc()的时候,其实并不会马上进行垃圾回收,甚至不一定会执行垃圾回收,查看系统源码可以看到 /** * Indicate ...
- void java.lang.System.gc()
void java.lang.System.gc() Runs the garbage collector. Calling the gc method suggests that the Java ...
- System.gc()和-XX:+DisableExplicitGC启动参数,以及DirectByteBuffer的内存释放
首先我们修改下JVM的启动参数,重新运行之前博客中的代码.JVM启动参数和测试代码如下: -verbose:gc -XX:+PrintGCDetails -XX:+DisableExplicitGC ...
随机推荐
- xLua热更新插件
一.xLua插件下载安装 1.从GitHub上搜索并下载插件 2.将文件复制到unity中 3.检查是否有错误 二.在unity中调用lua 1.简单调用 在c#脚本中使用LuaEnv类可以运行lua ...
- 使用TCP发送文件
客户端 package com.zy.demo3; import java.io.File; import java.io.FileInputStream; import java.io.IOExce ...
- 2019牛客暑期多校训练营(第八场)A-All-one Matrices(单调栈+思维)
>传送门< 题意:给你一个01矩阵,求出所有不可扩大的全为1的矩阵的个数 思路:比赛的时候想到了用单调栈,但是也只是想到了,并不知道怎么用,其实和之前求二维01矩阵中全为1的矩阵最大面积非 ...
- hdu1394Minimum Inversion Number
Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...
- Codeforces Round #652 (Div. 2) C. RationalLee 贪心
题意: t组输入,你有n个数,还有k个朋友,每一个朋友需要wi个数.意思就是你要给第i个朋友分配wi个数,输入保证w1+w2+...+wk=n 一个朋友的兴奋值是你分配给他的数中最大值加上最小值的和( ...
- AWS注册到连接
1. 注册AWS账号 https://www.cnblogs.com/cmt/p/13912814.html 2.注册完成之后,选择实例 Ubuntu,下载xxx.pem文件,查看实例得到ip 比如我 ...
- WSL2 VS Code远程开发.Net Core
修改 我们打开一个页面,随便修改一下,保存,结果会出现错误:Unable to write file (NoPermissions (FileSystemError): Error: EACCES: ...
- Unmanaged Exports not creating a .lib file
别用VS2017!别用VS2017!别用VS2017!去吧.
- Excel添加超链接
using Microsoft.Office.Interop.Excel; Worksheet sheet; public void AddLink(int row, int col, string ...
- Leetcode(877)-石子游戏
亚历克斯和李用几堆石子在做游戏.偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] . 游戏以谁手中的石子最多来决出胜负.石子的总数是奇数,所以没有平局. 亚历克斯和李轮流进行,亚历克斯先开始 ...