JVM 基础 (4) -- System.gc()

1. System.gc() 的作用

System.gc() 的作用是建议虚拟机进行一次 Full GC,但是虚拟机可以拒绝这个 GC 请求。

GC 线程是一种守护线程

2. 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) { //justRanFinalization=true
        Runtime.getRuntime().gc();
    }
}

从源码可以看出,只有当justRanFinalization=true的时候才会执行垃圾收集。
而当调用runFinalization()的时候,justRanFinalization 会变为 true

/**
* 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 请求记录下来,等到justRanFinalization=true的时候才会去执行 GC,justRanFinalization=true之后会允许一次system.gc()。之后再 call System.gc()时还会重复上面的行为。
所以System.gc()要跟System.runFinalization()要一起搭配使用才能确保虚拟机执行垃圾收集。

查看ZygoteInit.java,发现gc()runFinalizationSync()是配合使用的,这样才有效果

ZygoteInit 是 c 到 java 的入口,也是 java 的第一个进程
它的 main 方法主要做了三件事:

  1. 建立 socket 服务端
  2. 启动各种系统服务如 ams,wms,pms…
  3. 进入死循环,等待和处理 ams 通过 socket 传递的请求

想要了解 ZygoteInit 可以点这里

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();
}

3. 如何保证 System.gc() 有效

执行以下代码即可

System.gc();
System.runFinalization();
System.gc();

不过不建议这么做,因为 JVM 有自己的 GC 策略,根本不需要我们手动申请 GC

4. System.gc() 与 Runtime.getRuntime().gc() 的区别

  1. 垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,当一个对象不再被引用的时候,按照特定的垃圾收集算法来实现资源自动回收的功能。
  2. 每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime()方法获取当前运行时。
  3. java.lang.System.gc()实际上也是调用了java.lang.Runtime.getRuntime().gc(),两者的行为没有任何不同。
    public static void gc() {
        Runtime.getRuntime().gc();
    }
    
  4. 唯一的区别就是System.gc()写起来比Runtime.getRuntime().gc()简单点。其实基本没什么机会用到这个命令,因为这个命令只是建议 JVM 安排 GC 运行,还有可能完全被拒绝。 GC 本身会周期性的自动运行,由 JVM 决定运行的时机,而且现在的 JVM 版本有多种更智能的模式可以选择,还会根据运行的机器自动去做选择,就算真的有性能上的需求,也应该去对 GC 的运行机制进行微调,而不是通过使用这个命令来实现性能的优化。
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: `System.gc()` 是 Java 程序中的一个方法,它是在 Java 的 `java.lang` 包中的。这个方法的作用是请求 JVM 进行垃圾回收,但并不保证 JVM 一定会立即回收垃圾。它只是一个建议,由 JVM 决定是否执行回收操作。实际上,现代的 JVM 实现已经很智能,不需要开发人员明确地调用此方法来进行垃圾回收。 ### 回答2: System.gc();是Java中的一个方法调用,用于显示地触发垃圾回收。垃圾回收是Java虚拟机在运行时自动管理内存的一种机制,它负责自动回收不再被使用的对象的内存空间。当程序运行时,创建了一些对象,并且这些对象不再被引用时,Java虚拟机会自动回收这些对象所占用的内存空间,释放资源,这个过程就是垃圾回收。 而System.gc()方法的作用就是显式地调用垃圾回收器。虽然Java虚拟机会根据自身的策略自动触发垃圾回收,但是我们也可以通过调用System.gc()方法来建议虚拟机执行垃圾回收操作。调用System.gc()并不是立即执行垃圾回收,而是向垃圾回收器发送一个请求,告诉它有待回收的对象可以进行回收。 需要注意的是,System.gc()方法的调用并不会立即释放所有内存,也不能保证垃圾回收一定会执行。垃圾回收的具体执行时间是由JVM决定的,而且该方法的执行会造成一定的性能损失。因此,在编写代码时,我们不应该过分依赖于System.gc(),而是应该编写良好的代码结构和逻辑,避免出现内存泄漏等问题。 总之,System.gc()方法是用来手动触发垃圾回收的,它向垃圾回收器发送一个请求,告诉它有待回收的对象可以进行回收。但是需要注意的是,调用System.gc()并不能保证垃圾回收一定会执行,也不能立即释放所有内存,因此在编写代码时应该合理使用,不过度依赖于该方法。 ### 回答3: System.gc()是Java中的一个方法,用于显式地请求垃圾回收器进行垃圾回收。 在Java中,垃圾回收器负责自动回收不再使用的内存,释放掉这些内存供其他程序使用,从而避免了内存泄漏的问题。系统会自动进行垃圾回收,但是我们也可以使用System.gc()方法来主动触发垃圾回收。 当我们调用System.gc()方法时,会向JVM发送一个垃圾回收的请求,但是具体是否立即进行垃圾回收以及回收的效果,取决于JVM的实现。 值得注意的是,尽管我们可以调用System.gc()方法来主动触发垃圾回收,但是这并不意味着每次调用都会导致垃圾回收的立即执行。实际上,JVM会根据自身的策略和算法来决定何时进行垃圾回收,以及要回收多少的内存。 在一般情况下,我们并不需要手动调用System.gc()方法,因为JVM能够根据需要自动进行垃圾回收。只有在某些特殊情况下,比如我们需要尽快回收大量的内存时,可能会使用System.gc()方法来主动触发垃圾回收。 总之,System.gc()方法是Java中一个用于主动触发垃圾回收的方法。但是我们要注意,不要滥用这个方法,因为JVM能够自动进行垃圾回收,并且过多地调用System.gc()方法可能会影响程序的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值