GC

2019-10-27  本文已影响0人  紫色红色黑色

面试题

请写一段程序,让其运行时的表现为触发5次ygc,然后3次fgc,然后3次ygc,然后1次fgc,请给出代码以及启动参数。从网上找到答案,决定试一下。

代码

下面程序参考代码触发JVM的Full GC和Young GC

1.程序

public class GcDemo {

    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {

        System.out.println("0.------");

        List<byte[]> list = new ArrayList<>();

        for (int i = 0; i < 11; i++) {
            byte[] e = new byte[3 * _1MB];
            list.add(e);
        }

        System.out.println("1.------");
    }
}

2.jvm参数

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xms41m -Xmx41m -Xmn10m -XX:+UseParallelGC

3.输出日志

0.------
2019-10-23T00:21:09.011-0800: [GC (Allocation Failure) [PSYoungGen: 5575K->695K(9216K)] 5575K->3775K(41984K), 0.0126284 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2019-10-23T00:21:09.025-0800: [GC (Allocation Failure) [PSYoungGen: 7161K->608K(9216K)] 10241K->9832K(41984K), 0.0114943 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
2019-10-23T00:21:09.039-0800: [GC (Allocation Failure) [PSYoungGen: 6965K->544K(9216K)] 16189K->15912K(41984K), 0.0142043 secs] [Times: user=0.00 sys=0.01, real=0.02 secs] 
2019-10-23T00:21:09.054-0800: [GC (Allocation Failure) [PSYoungGen: 6829K->544K(9216K)] 22197K->22056K(41984K), 0.0085964 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2019-10-23T00:21:09.064-0800: [GC (Allocation Failure) [PSYoungGen: 6835K->592K(9216K)] 28347K->28248K(41984K), 0.0155588 secs] [Times: user=0.00 sys=0.01, real=0.01 secs] 
2019-10-23T00:21:09.080-0800: [Full GC (Ergonomics) [PSYoungGen: 592K->0K(9216K)] [ParOldGen: 27656K->28155K(32768K)] 28248K->28155K(41984K), [Metaspace: 3301K->3301K(1056768K)], 0.0244979 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
1.------
Heap
 PSYoungGen      total 9216K, used 6460K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 78% used [0x00000007bf600000,0x00000007bfc4f138,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 32768K, used 28155K [0x00000007bd600000, 0x00000007bf600000, 0x00000007bf600000)
  object space 32768K, 85% used [0x00000007bd600000,0x00000007bf17eec8,0x00000007bf600000)
 Metaspace       used 3305K, capacity 4556K, committed 4864K, reserved 1056768K
  class space    used 362K, capacity 392K, committed 512K, reserved 1048576K

4.gc日志

各类gc日志可以参考JVM各类GC日志剖析

[GC (Allocation Failure) [PSYoungGen: 5575K->695K(9216K)] 5575K->3775K(41984K), 0.0126284 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

语句 描述
GC 新生代GC
5575K->695K(9216K) 新生代总内存9216K,GC前占用5575K,GC后占用695K
0.0126284 secs GC花费时间
Times: user=0.01 sys=0.00, real=0.01 secs 用户态占用时间,内核态占用时间,实际占用时间
Full GC (Ergonomics) [PSYoungGen: 592K->0K(9216K)] [ParOldGen: 27656K->28155K(32768K)] 28248K->28155K(41984K), [Metaspace: 3301K->3301K(1056768K)], 0.0244979 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

语句 描述
Full GC 针对整个堆的GC
PSYoungGen: 592K->0K(9216K) 新生代总内存9216K,GC前占用592K,GC后占用0K
ParOldGen: 27656K->28155K(32768K) 老生代总内存32768K,GC前占用27656K,GC后占用28155K
Metaspace: 3301K->3301K(1056768K) 元空间总内存1056768K,GC前占用3301K,GC后占用3301K

gc日志参考JVM各类GC日志剖析

字段 描述 gc
DefNew Default New Generation Serial
ParNew Parallel New Generation ParNew
PSYoungNew Parallel Scavenge

5.GC算法
JVM堆内存,根据对象存活特点使用分代算法。分为新生代、老生代、MetaSpace。
新生代中对象“朝生夕死”,使用复制算法(Copying)。新生代分为Eden区、From survivor区、To survivor区。分配内存时,先使用Eden。垃圾回收时,将不可回收内存对象复制到To survivor中,大对象和存活时间长的对象复制到老生代。将Eden、From survivor中的内存全部回收。下一次垃圾回收时,将不可回收内存对象复制到From survivor中,全部回收Eden、To survivor中的内存。
老生代中对象存活时间久,使用标记压缩算法(Mark-Compact)。垃圾回收时,先标记可回收内存对象,然后将其回收,在将不可回收内存整理压缩。避免内存碎片。
判断对象是否可回收,使用可达性分析算法(Reachability-Analysis)。使用GC Roots为根节点,向下搜索。一个对象如果没有GC Roots引用他,则称该对象不可达,可回收。

6.GC触发条件
发生在新生代中的内存回收成为Minor GC。当在Eden中分配内存而Eden内存不够时会触发GC。
Full GC是针对整个堆内存进行的GC。当触发Minor GC时,新生代平均晋升到老生代的内存大小大于老生代剩余的内存大小时触发Full GC。

垃圾收集器

  1. 常用的垃圾收集器

常用的HotSpot垃圾收集器如下所示。

垃圾收集器.png

使用命令查看jvm使用那种gc

# 命令
java -XX:+PrintCommandLineFlags -version
# 显示
-XX:InitialHeapSize=134217728 -XX:MaxHeapSize=2147483648 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
  1. 垃圾收集器指标
收集器 串行、并行or并发 新生代/老年代 算法 目标 适用场景 命令
Serial 串行 新生代 复制算法 响应速度优先 单CPU环境下的Client模式 -XX:+UseSerialGC
Serial Old 串行 老年代 标记-整理 响应速度优先 单CPU环境下的Client模式、CMS的后备预案 上一项启动,这一项就启动
ParNew 并行 新生代 复制算法 响应速度优先 多CPU环境时在Server模式下与CMS配合 和CMS配合使用
Parallel Scavenge 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务 -XX:+UseParallelGC
Parallel Old 并行 老年代 标记-整理 吞吐量优先 在后台运算而不需要太多交互的任务 上一条启动,自动启动该项,如果不想用可以使用-XX:-UseParallelOldGC关闭
CMS 并发 老年代 标记-清除 响应速度优先 集中在互联网站或B/S系统服务端上的Java应用 -XX:+UseConcMarkSweepGC启动,新生代启动ParNew
G1 并发 both 标记-整理+复制算法 响应速度优先 面向服务端应用,将来替换CMS -XX:+UseG1GC
  1. CMS

并发标记清除算法,参考JVM 之 ParNew 和 CMS 日志分析

  1. G1
    内存引入region,将堆内存分为2048个region。一个region可以是Eden、Survival、Old区。

引用

Java HotSpot VM Options
Java JVM 参数设置大全
JVM 系列文章之 Full GC 和 Minor GC
JVM 垃圾回收器工作原理及使用实例介绍
Major GC和Full GC的区别是什么?触发条件呢?
G1垃圾回收器调优
Java Hotspot G1 GC的一些关键技术
https://plumbr.io/handbook/what-is-garbage-collection
7种垃圾收集器
垃圾回收算法与 JVM 垃圾回收器综述
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
详解CMS垃圾回收机制

上一篇 下一篇

猜你喜欢

热点阅读