美文网首页性能
Android到底要不要手动调用System.gc()

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

作者: Koudle | 来源:发表于2017-03-28 20:59 被阅读1731次

导语

曾几何时,我们一直纠结于到底要不要手动调用System.gc(),有的人说这样调用太丑陋,完全没必要,JVM会帮我们处理好的,有的人说可以调用,这样可以及时释放内存,现在可以明确的告诉你,在Android5.0及以上手动调用System.gc()完全没必要,因为你调了也完全触发不了gc,为什么会这样说呢?

Talk is cheap,show you the code

我们直接看代码!

源码

Android5.0之前的代码

如下:

/**
 * Indicates to the VM that it would be a good time to run the
 * garbage collector. Note that this is a hint only. There is no guarantee
 * that the garbage collector will actually be run.
 */
public static void gc() {
    Runtime.getRuntime().gc();
}

这个看上去完全没问题

Android 5.0及以后的代码

先看System.gc()到底做了什么,如下:

/**
 * Indicates to the VM that it would be a good time to run the
 * garbage collector. Note that this is a hint only. There is no guarantee
 * that the garbage collector will actually be run.
 */
public static void gc() {
    boolean shouldRunGC;
    synchronized(lock) {
        shouldRunGC = justRanFinalization;
        if (shouldRunGC) {
            justRanFinalization = false;
        } else {
            runGC = true;
        }
    }
    if (shouldRunGC) {
        Runtime.getRuntime().gc();
    }
}

简单易懂啊,前面就是一些赋值啊判断啊,直接看最重要的一句

    if (shouldRunGC) {
        Runtime.getRuntime().gc();
    }

可以看到,只有当shouldRunGC为true时,才会真的去gc,而shouldRunGC的值其实不就是justRanFinalization的值吗,那好,我们全局搜索一下,发现justRanFinalization出现的地方取值可数,只有两个地方:

1、定义的地方

/**
 * If we just ran finalization, we might want to do a GC to free the finalized objects.
 * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
 */
private static boolean justRanFinalization;

2、赋值的地方

/**
 * Provides a hint to the VM that it would be useful to attempt
 * to perform any outstanding object finalization.
 */
public static void runFinalization() {
    boolean shouldRunGC;
    synchronized(lock) {
        shouldRunGC = runGC;
        runGC = false;
    }
    if (shouldRunGC) {
        Runtime.getRuntime().gc();
    }
    Runtime.getRuntime().runFinalization();
    synchronized(lock) {
        justRanFinalization = true;
    }
}

哇咔咔,so easy,这时一个函数出现在我们眼前runFinalization(),这个函数是干嘛的?和System.gc()有什么关系,直接看函数的注释,其实就是执行对象的finalize()方法,但最关键的是,只有在这个地方是justRanFinalization的值才会赋为true,仔细观察,还有一个变量runGC,在System.gc()里会赋值为true,而在System.runFinalization()里只有runGC为
true时,才会真的去触发gc

总结

所以说只是单纯的调用System.gc(),在Android5.0以上什么也不会发生,要么是

  1. System.gc()和System.runFinalization()同时调用
  2. 直接调用Runtime.getRuntime().gc()

相关文章

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

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

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

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

  • Java面试题

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

  • Java的对象引用类型

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

  • R大部分文章整理

    整理rednaxelafx.iteye.com上适合的内容 手动System.gc()与JVM自动gc有什么根本上...

  • 11.07

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

  • ViewPager 报Unable to find resour

    对于手动创建的ViewPager,必须调用setId()方法设置一个id。否则,就会报android.conten...

  • full GC触发的条件

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

  • -XX:+DisableExplicitGC

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

  • FULL GC触发的原因

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

网友评论

    本文标题:Android到底要不要手动调用System.gc()

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