美文网首页性能
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()

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