总结:

如果jvm参数中设置了-XX:+DisableExplicitGC,那么代码中手动调用System.gc()就不会生效。而有些框架中因为是使用的堆外内存,必须手动调用System.gc()来释放。如果禁用掉就会导致堆外内存使用一直增长,造成内存泄露。

详解:

直接内存与System.gc()

System.gc()默认会触发一次Full GC,如果在代码中不小心调用了System.gc()会导致JVM间歇性的暂停,但有些NIO框架
比如Netty框架经常会使用DirectByteBuffer来分配堆外内存,在分配之前会显式的调用System.gc(),如果开启了DisableExplicitGC
这个参数,会导致System.gc()调用变成一个空调用,没有任何作用,反而会导致Netty框架无法申请到足够的堆外内存,从而产生
java.lang.OutOfMemoryError: Direct buffer memory

既然是堆外内存,为什么触发Full GC会有助于回收堆外内存呢,Full GC不是只回收JVM的堆内存吗?这就要了解下DirectByteBuffer的回收机制了,DirectByteBuffer没有finalizer,它的native memory的清理工作是通过sun.misc.Cleaner自动完成的,而sum.misc.Cleaner是一种基于虚引用的回收工具,从JDK源码也可以看到:

public class Cleaner extends PhantomReference<Object>

当GC检查到Cleaner的引用变成虚引用可达时,reference-handler线程会调用Cleaner的clean方法回收内存,这个机制可以在
java.lang.ref.Reference$ReferenceHandler里看到,Reference类加载的时候会创建reference-handler线程:

public void run() {for (;;) {//省略了一些// Fast path for cleanersif (r instanceof Cleaner) {((Cleaner)r).clean();continue;}}
static {ThreadGroup tg = Thread.currentThread().getThreadGroup();for (ThreadGroup tgn = tg;tgn != null;tg = tgn, tgn = tg.getParent());Thread handler = new ReferenceHandler(tg, "Reference Handler");/* If there were a special system-only priority greater than* MAX_PRIORITY, it would be used here*/handler.setPriority(Thread.MAX_PRIORITY);handler.setDaemon(true);handler.start();}

JVM在做Full GC时会对引用作处理(reference processing),当GC检测到Cleaner的引用变成虚可达时,引用Handler线程会触发Cleaner对DirectByteBuffer对象作清理工作.

CMS垃圾回收器下的推荐配置

既然不推荐使用DisableExplicitGC这个参数,那有没有什么办法能尽量减少显式调用System.gc()带来的GC停顿呢,JVM提供了
ExplicitGCInvokesConcurrent和ExplicitGCInvokesConcurrentAndUnloadsClasses这两个参数来保证显式调用System.gc()
触发的是一个并发GC周期而不是Full GC,这两个参数只能配合CMS使用(-XX:+UseConcMarkSweepGC):

CMS GC周期内也会做reference-processing,因此也能够触发对DirectByteBuffer内存的回收,减少了Full GC带来的长时间
停顿。

当没有开启DisableExplicitGC这个参数时,你会发现JVM每个小时会执行一次Full GC,这是因为JVM在做分布式GC,为RMI服务的,
可以通过sun.rmi.dgc.server.gcInterval这个参数来修改GC间隔,默认是一个小时。

System.gc常识

  • system.gc其实是做一次full gc
  • system.gc会暂停整个进程
  • system.gc一般情况下我们要禁掉,使用-XX:+DisableExplicitGC
  • system.gc在cms gc下我们通过-XX:+ExplicitGCInvokesConcurrent来做一次稍微高效点的GC(效果比Full GC要好些)
  • system.gc最常见的场景是RMI/NIO下的堆外内存分配等

参考:http://docs.oracle.com/javase/6/docs/technotes/guides/rmi/sunrmiproperties.html

-XX:+DisableExplicitGC弊端相关推荐

  1. JVM -XX: 参数介绍

    功能开关: 参数 默认值或限制 说明 参数 默认值 功能 -XX:-AllowUserSignalHandlers 限于Linux和Solaris,默认不启用 允许为java进程安装信号处理器,信号处 ...

  2. JVM运行参数之-X和-XX参数

    -X参数 JVM的-X参数是非标准参数,在不同版本的jvm中,参数可能会有所不同,可以通过java -X查看非标准参数. C:\Users\zjq>java -X-Xmixed 混合模式执行 ( ...

  3. JVM底层原理之标配参数、X和XX参数

    一.JVM的参数类型 (1)标配参数(以-开头)    java -version java -help java -showversion 在JDK各个版本之间稳定,很少有大的变化.   [标准VM ...

  4. Java启动参数(-, -X, -XX参数)详解

    目录 Java启动参数分类 一.JVM标准参数(-) 获取方法: java -help 二.JVM非标准参数(-X) 获取方法: java -X 三.JVM非Stable参数(-XX) 获取方法:   ...

  5. JVM 启动参数规则:-、-X、-XX、-D表示什么意思?

    通过JVM运行一个java程序的时候,我们通常会用java -jar xxxx.jar 的命令,我们通常都会根据情况配置很多的运行参数. 例如: /usr/local/java/jdk1.8.0_13 ...

  6. JVM参数-XX:+HeapDumpOnOutOfMemoryError使用方法

    1.配置方法 在JAVA_OPTIONS变量中增加 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${目录}. 例如:export JAVA_OPT ...

  7. JVM -XX:MaxDirectMemorySize

    -XX:MaxDirectMemorySize 该参数指定了DirectByteBuffer能分配的空间的限额,如果没有显示指定这个参数启动jvm,默认值是xmx对应的值. DirectByteBuf ...

  8. tomcat 启动参数 Xms, Xmx, XX:MaxNewSize, XX:PermSize, -XX:MaxPermSize, Djava.awt.headless

    在 tomcat/bin/catalina.sh 的 第一行#!/bin/sh 下添加 JAVA_OPTS="-server -Xms512m -Xmx1024m -XX:MaxNewSiz ...

  9. java垃圾回收system_java应用性能调优之详解System的gc垃圾回收方法

    1.什么是System.gc()? System.gc()是用Java,C#和许多其余流行的高级编程语言提供的API.当它被调用时,它将尽最大努力从内存中清除垃圾(即未被引用的对象).名词解释:GC, ...

最新文章

  1. Linux Kernel aarch64 Crypto原理和框架介绍
  2. Trie实现(C++)
  3. 【Tomcat】如何解决catalina.out文件过大的问题
  4. 获取父线程 java_java子线程中获取父线程的threadLocal中的值
  5. (最短路)HDU Today(hdu2112)
  6. 方法的重载 c# 1613699221
  7. 0-10不断循环的js
  8. windows下创建vp9的VS版本
  9. MAC下邮件客户端操作——解决无法登陆GMail IMAP服务器
  10. gprs java_GPRS类型一览
  11. 多线程与并发系列之CompletableFuture
  12. 关于JPsh极光推送的基本用法和通知介绍
  13. 天耀18期 – 05.面向对象-封装【作业】.
  14. Trie树 与 三分树(Ternary Trees)
  15. android-studio推荐模拟器,Android studio 三大模拟器比较,强烈推荐第三种
  16. TED-4-美好人生的定义
  17. python写cdr插件_(如何(用Python)写一个(Lisp)解释器(下))
  18. gitlab迁移坑深路远
  19. 阿里云docker环境搭建和问题解决
  20. 计算信号波形上升时间下降时间算法软件(Labview版)

热门文章

  1. python学习笔记(一)数据处理
  2. 如何使用python insert插入数据
  3. ssh登录主机报错: Unable to negotiate with 172.222.222.243 port 22: no matching key exchange method found.
  4. 对ZZL字符串匹配算法的改 ——ZZL最短匹配定理
  5. 知识抽取学习笔记:面向非结构化数据的抽取
  6. ps ctrl+shift+j 切割瓶子
  7. mbp网速很慢_macbook无线上网很慢怎么办 macbook无线上网很慢解决方法
  8. Vue 3.0终于来了!官方凌晨开源代码,导读一波
  9. David Silver强化学习公开课自学笔记——Lec2马尔科夫决策过程
  10. 坑爹的AWS免费服务