JVM&GC(三)-System.gc()方法

前言

在默认情况下,System.gc()会显示直接触发Full GC,同时对老年代和新生代进行回收。而一般情况下,垃圾回收应该是自动进行的,无需手工触发,否则就太麻烦了。

示例

public class TestGC {
    public static void main(String[] args) {
        new TestGC();
        System.gc();
        System.runFinalization();
    }
}

如果在idea查看日志输出,需要在Run–>Edit Configuration–>VM Options中设置

-XX:+PrintGCDetails

图片.png
打印结果

[GC (System.gc()) [PSYoungGen: 8489K->1707K(38400K)] 8489K->1715K(125952K), 0.0070544 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (System.gc()) [PSYoungGen: 1707K->0K(38400K)] [ParOldGen: 8K->1568K(87552K)] 1715K->1568K(125952K), [Metaspace: 3357K->3357K(1056768K)], 0.0228661 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
Heap
 PSYoungGen      total 38400K, used 998K [0x00000000d5f00000, 0x00000000d8980000, 0x0000000100000000)
  eden space 33280K, 3% used [0x00000000d5f00000,0x00000000d5ff9b20,0x00000000d7f80000)
  from space 5120K, 0% used [0x00000000d7f80000,0x00000000d7f80000,0x00000000d8480000)
  to   space 5120K, 0% used [0x00000000d8480000,0x00000000d8480000,0x00000000d8980000)
 ParOldGen       total 87552K, used 1568K [0x0000000081c00000, 0x0000000087180000, 0x00000000d5f00000)
  object space 87552K, 1% used [0x0000000081c00000,0x0000000081d883f0,0x0000000087180000)
 Metaspace       used 3369K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 366K, capacity 388K, committed 512K, reserved 1048576K

在这个例子中,一个新的对象被创建,由于它没有被使用,所以该对象迅速地变为不可达(Unreachable)。
GC开头的说明此次垃圾回收为Minor GC,而Full GC开头的说明此次垃圾回收为stop-the-world的类型。
PSYoungGen表示年轻代,ParOldGen表示老年代。
方括号内的8489K->1707K(38400K)表示GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)。
方括号外的8489K->1715K(125952K)表示GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)。
0.0070544 secs表示该内存区域本次GC所占用的时间,单位是秒。有的收集器会给出更具体的时间数据,如[Times: user=0.00 sys=0.00, real=0.01 secs],这里的user、sys、real与Linux的time命令所输出的时间含义一致,分别代表用户态消耗的CPU时间、内核态消耗的CPU时间、操作从开始到结束所经过的墙钟时间。CPU时间和墙钟时间的区别是,墙钟时间包括各种非运算的等待耗时,如等待磁盘I/O、等待线程阻塞,而CPU时间不包括这些耗时,但当系统有多CPU或者多核的话,多线程操作会叠加这些CPU时间,所以若看到user或sys时间超过real时间也是完全正常的。
eden、from、to表示年轻代中各区域的划分。
Metaspace表示元空间的大小,这里用的是JDK1.8,如果是JDK1.7则没有该区域。

默认情况下,即使System.gc()生效,他会使用传统的Full GC方式回收整个堆内存垃圾,而会忽略选项中的USeG1GC,比如我们设置-XX:+PrintGCDetails -XX:+UseG1GC,运行代码,输出结果如下:

[GC pause (G1 Evacuation Pause) (young), 0.0065937 secs]
   [Parallel Time: 1.2 ms, GC Workers: 4]
      [GC Worker Start (ms): Min: 262.2, Avg: 262.5, Max: 263.4, Diff: 1.2]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.2, Max: 0.3, Diff: 0.3, Sum: 0.7]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0]
      [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.7, Max: 0.9, Diff: 0.9, Sum: 2.7]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.2]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 4]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [GC Worker Total (ms): Min: 0.0, Avg: 0.9, Max: 1.2, Diff: 1.2, Sum: 3.6]
      [GC Worker End (ms): Min: 263.4, Avg: 263.4, Max: 263.4, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.0 ms]
   [Other: 5.4 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 5.3 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.0 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 6144.0K(6144.0K)->0.0B(12.0M) Survivors: 0.0B->1024.0K Heap: 7086.4K(128.0M)->1579.0K(128.0M)]
 [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (System.gc())  2078K->1176K(8192K), 0.0057042 secs]
   [Eden: 1024.0K(12.0M)->0.0B(3072.0K) Survivors: 1024.0K->0.0B Heap: 2078.9K(128.0M)->1176.6K(8192.0K)], [Metaspace: 3358K->3358K(1056768K)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 garbage-first heap   total 8192K, used 1176K [0x0000000081c00000, 0x0000000081d00040, 0x0000000100000000)
  region size 1024K, 1 young (1024K), 0 survivors (0K)
 Metaspace       used 3368K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 366K, capacity 388K, committed 512K, reserved 1048576K

可以看出G1 GC并没有并发执行。打开虚拟机选项 -XX:+ExplicitGCInvokesConcurrent后可改变这种默认行为

[GC pause (System.gc()) (young) (initial-mark), 0.0017516 secs]
   [Parallel Time: 1.4 ms, GC Workers: 4]
      [GC Worker Start (ms): Min: 254.2, Avg: 254.3, Max: 254.5, Diff: 0.3]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.4, Max: 1.4, Diff: 1.3, Sum: 1.8]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0]
      [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.8, Max: 1.1, Diff: 1.0, Sum: 3.0]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Termination Attempts: Min: 1, Avg: 28.3, Max: 47, Diff: 46, Sum: 113]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [GC Worker Total (ms): Min: 1.1, Avg: 1.3, Max: 1.4, Diff: 0.3, Sum: 5.0]
      [GC Worker End (ms): Min: 255.6, Avg: 255.6, Max: 255.6, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.0 ms]
   [Other: 0.3 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.2 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.0 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 7168.0K(14.0M)->0.0B(12.0M) Survivors: 0.0B->2048.0K Heap: 7676.5K(128.0M)->1665.6K(128.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC concurrent-root-region-scan-start]
[GC concurrent-root-region-scan-end, 0.0007669 secs]
[GC concurrent-mark-start]
[GC concurrent-mark-end, 0.0001007 secs]
[GC remark [Finalize Marking, 0.0000437 secs] [GC ref-proc, 0.0000645 secs] [Unloading, 0.0004621 secs], 0.0006229 secs]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC cleanup 1665K->1665K(128M), 0.0001751 secs]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 garbage-first heap   total 131072K, used 1665K [0x0000000081c00000, 0x0000000081d00400, 0x0000000100000000)
  region size 1024K, 3 young (3072K), 2 survivors (2048K)
 Metaspace       used 3373K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 366K, capacity 388K, committed 512K, reserved 1048576K

调用System.gc()也仅仅是一个请求垃圾回收的建议,JVM接收这个消息后并不是立即做垃圾回收,而是对几个垃圾回收算法做加权,使垃圾回收操作容易发生或者提早发生,或回收较多而已。

个人博客
腾讯云社区
掘金
CSDN
简书
GitHub
码云
OSCHINA
Segmentfault
公众号:wx.jpg

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: finalize方法是Java中的一个方法,用于在对象被垃圾回收之前执行一些清理操作。当一个对象不再被引用时,垃圾回收器会在某个时间点自动回收该对象。在回收之前,如果该对象有finalize方法,垃圾回收器会先调用该方法,然后再回收对象。finalize方法可以用来释放一些资源,如文件句柄、网络连接等。 system.gc是Java中的一个方法,用于强制执行垃圾回收。当Java程序运行时,垃圾回收器会自动回收不再被引用的对象,但是垃圾回收的时间是不确定的。如果程序需要立即回收一些对象,可以调用system.gc方法。但是,调用system.gc方法并不一定会立即回收对象,因为垃圾回收器的行为是不确定的。因此,一般情况下不建议频繁调用system.gc方法,因为这会影响程序的性能。 ### 回答2: finalize方法是Java中的一个重要方法,它属于Object类的一部分。当一个对象即将被垃圾回收器回收时,垃圾回收器会首先调用该对象的finalize方法。finalize方法可以被子类重写以执行结束前的清理工作,比如关闭文件或释放资源等。finalize方法的定义如下: protected void finalize() throws Throwable {} 而System.gc()方法是用来建议垃圾回收器执行垃圾回收操作的。它是Java.lang.System类的一个静态方法。调用System.gc()并不会立即执行垃圾回收,而是在有垃圾回收器线程可用时,告知垃圾回收器进行回收操作。但是,垃圾回收器是否执行回收操作以及具体的时间,是由垃圾回收器自行决定的。System.gc()方法的定义如下: public static void gc() {} 总而言之,finalize方法是一个对象级别的方法,用于在对象被垃圾回收之前进行一些清理操作。而System.gc()方法是建议垃圾回收器执行垃圾回收的方法。它们的使用时机和效果是不同的。在实际编程中,应当尽量避免使用finalize方法,因为它的执行时间是不确定的,可能会影响程序的性能。同时,也不应过度依赖System.gc()方法,因为垃圾回收器是由JVM进行管理的,我们无法强制要求其立即执行回收操作。 ### 回答3: finalize方法是Java中的一个特殊方法,它是Object类中的一个方法,用来进行对象的清理和资源回收。当一个对象即将被垃圾回收器回收时,finalize方法会被自动调用。 finalize方法的主要作用是允许程序员在对象被销毁之前进行一些清理工作,例如关闭文件、释放资源、断开网络连接等。这个方法可以被重写,以便在子类中进行特定的清理操作。 然而,finalize方法并不保证一定会被执行,因为垃圾回收器的工作是由JVM控制的,无法完全预测对象何时被回收。finalize方法的调用通常是不可预测和不确定的,因此它并不是程序中必要的一部分。 与finalize方法相比,System.gc是一个用于显示请求垃圾回收的方法。通过调用System类中的gc方法,可以建议JVM在当前时间进行垃圾回收。然而,这只是一个建议,具体是否执行回收操作仍然取决于JVM的实现。 在正常情况下,应该避免过度依赖finalize方法和频繁使用System.gc方法。因为垃圾回收是由JVM自动管理的,过度使用finalize方法和频繁调用System.gc方法可能会影响程序的性能和效率。应该尽量使用面向对象的设计原则,在对象不再使用时及时释放资源,而不是依赖于finalize方法和手动垃圾回收。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值