美文网首页
规避代码级别的System.gc调用

规避代码级别的System.gc调用

作者: KnowLifeDeath | 来源:发表于2017-11-06 00:04 被阅读51次

规避代码级别的System.gc调用

源起:

System.gc()的调用, 会使用Full GC的方式回收整个堆而会忽略CMS或G1等相关回收器,Full GC可能导致长时间的STW,这个对于响应要求比较高的系统影响是致命的,有很多操作可以尽量减少Full GC频次及Full GC的操作时间,今天要涉及的是如何规避代码中直接调用System.gc导致的Full GC.

方法:

-XX:+DisableExplicitGC 禁止程序中调用System.gc(), 加了此参数, 程序若有调用, 返回的空函数调用。

该参数是如何起作用的?

下面来走一个System.gc的实现流程:

Step01:

java.lang.System.gc();

Step02:

java.lang.System

/**
* Runs the garbage collector.
* <p>
* Calling the <code>gc</code> method suggests that the Java Virtual
* Machine expend effort toward recycling unused objects in order to
* make the memory they currently occupy available for quick reuse.
* When control returns from the method call, the Java Virtual
* Machine has made a best effort to reclaim space from all discarded
* objects.
* <p>
* The call <code>System.gc()</code> is effectively equivalent to the
* call:
* <blockquote><pre>
* Runtime.getRuntime().gc()
* </pre></blockquote>
*
* @see    java.lang.Runtime#gc()
*/
public static void gc() {
    Runtime.getRuntime().gc();
}

Step03:

java.lang.Runtime

/**
* Runs the garbage collector.
* Calling this method suggests that the Java virtual machine expend
* effort toward recycling unused objects in order to make the memory
* they currently occupy available for quick reuse. When control
* returns from the method call, the virtual machine has made
* its best effort to recycle all discarded objects.
* <p>
* The name <code>gc</code> stands for "garbage
* collector". The virtual machine performs this recycling
* process automatically as needed, in a separate thread, even if the
* <code>gc</code> method is not invoked explicitly.
* <p>
* The method {@link System#gc()} is the conventional and convenient
* means of invoking this method.
*/
public native void gc();

Step04:

\openjdk-8-src-b132-03_mar_2014\openjdk\jdk\src\share\native\java\lang\Runtime.c

JNIEXPORT void JNICALL
Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
{
    JVM_GC();
}

Step05:

到这一步其实很明了了,无需多做解释。
\openjdk-8-src-b132-03_mar_2014\openjdk\hotspot\src\share\vm\prims\jvm.cpp

JVM_ENTRY_NO_ENV(void, JVM_GC(void))
  JVMWrapper("JVM_GC");
  if (!DisableExplicitGC) {
    Universe::heap()->collect(GCCause::_java_lang_system_gc);
  }
JVM_END

Step06:

该参数默认是false,显式设置时为true,直接跳出Full GC操作.
\openjdk-8-src-b132-03_mar_2014\openjdk\hotspot\src\share\vm\runtime\globals.hpp

  product(bool, DisableExplicitGC, false,                                  \
          "Ignore calls to System.gc()")                                    \

附录

java源码中的native方法是不能直接在jdk中看到的,因为jdk不是开源的,要看到的话需要sun授权才行,现在只有openjdk是被sun公司授权,所以要查看的话,得下载完整的OpenJDK源码包。比如此次分析用的是这个openjdk-8-src-b132-03_mar_2014.zip.

相关文章

  • 规避代码级别的System.gc调用

    规避代码级别的System.gc调用 源起: System.gc()的调用, 会使用Full GC的方式回收整个堆...

  • -XX:+DisableExplicitGC

    这是一个开关参数,默认是开启的,其作用是禁止代码中显示的调用GC。代码如何显示调用GC呢,通过System.gc(...

  • Java面试题

    1.调用system.gc()是否会立即回收垃圾? 其实当我们调用system.gc()的时候并不会马上进行垃圾回...

  • Full gc那些事

    日志s: 1、system.gc一般是代码调用 1、cms full gc一点没释放?jmap分析是否内存泄漏 R...

  • Java的对象引用类型

    强制系统垃圾回收的两种方式: 调用System类的gc()静态方法:System.gc()。调用Runtime对象...

  • 11.07

    你能保证 GC 执行吗?不能,虽然你可以调用 System.gc() 或者 Runtime.getRuntime(...

  • full GC触发的条件

    full GC触发的条件 直接调用 直接调用System.gc 旧生代空间不足 旧生代空间只有在新生代对象转入...

  • FULL GC触发的原因

    -------引用自百度知道hao23474206 的回答 除直接调用System.gc外,触发Full GC执行...

  • Full GC 的一些常见原因

    1. System.gc()方法的调用 2. 老年代不足 3. 永久代不足 4. concurrent mode ...

  • Android到底要不要手动调用System.gc()

    导语 曾几何时,我们一直纠结于到底要不要手动调用System.gc(),有的人说这样调用太丑陋,完全没必要,JVM...

网友评论

      本文标题:规避代码级别的System.gc调用

      本文链接:https://www.haomeiwen.com/subject/evlkmxtx.html