Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 691|回复: 0

JVM(5)——调用System.gc没有立即执行的解决方法

[复制链接]
  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 802 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726006
    发表于 2021-9-5 16:52:28 | 显示全部楼层 |阅读模式

    查看源码

    当我们调用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();
            }
        }

    也就是justRanFinalization=true的时候才会执行

    查找发现当调用runFinalization()的时候justRanFinalization变为true
    下面是runFinalization()的源码

    /**
    * 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;
            }
    }

    其实当我们直接调用System.gc()只会把这次gc请求记录下来,等到runFinalization=true的时候才会先去执行GC,runFinalization=true之后会在允许一次system.gc()。之后在call System.gc()还会重复上面的行为。
    所以System.gc()要跟System.runFinalization()一起搭配使用才好。
    查看ZygoteInit.java 里面 gc()和runFinalizationSync()是配合使用的,这样才有效果

    static void gcAndFinalize() {
        final VMRuntime runtime = VMRuntime.getRuntime();
    
        /* runFinalizationSync() lets finalizers be called in Zygote,
        * which doesn't have a HeapWorker thread.
        */
        System.gc();
        runtime.runFinalizationSync();
        System.gc();
    }

    解决方案

    由此可见,当我们需要调用的System.gc()的时候 要这样才会执行

    // 强制调用gc释放内存
    System.gc();
    System.runFinalization();

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-14 19:48 , Processed in 2.871908 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表