• 今日份学习: Java 的 GC


    Java 的 GC

    java garbage collection pdf

    内存管理

    两个流派:

    1. 手动内存管理(C/C++)

    2. 自动内存管理(Java/Python...)

      1. 引用计数(Reference Counting)
      • 问题:循环引用

        • 引用计数的缺点

      1. 标记清除(Mark and Sweep)
      • 可达性分析

    • 线程对应方法栈

    • 方法对应栈帧



    内存碎片化

    • 长期工作的内存会出现碎片化
      • 总可用空间仍然足够,但是无法分配大对象
    • 垃圾回收 = 回收可用空间 + 压缩内存



    引用的类型

    • 强引用 Strong Reference:用到的都是强引用
    • 软引用 Soft Reference:内存不够的时候会回收他们
    • 弱引用 Weak Reference:一GC就回收他们
    • 影子引用 Phantom Reference:只能拿到影子,拿不到引用本身



    GC基本原理

    1. 哪些东西是GC Roots?

    • 活的线程(java.lang.Thread)
    • 类的静态成员
    • 线程方法栈所引用的对象
    • JNI(Java Native Interface)引用的对象
    • 分代GC时其他代的对象

    2. GC发生了什么?

    1.

    • Stop the world (STW)
    • 清除垃圾
    • 压紧内存

    2.

    • 拷贝



    对象的分代假设

    1. 对象的分代假设

    • 内存分代
      • 年轻代(Young Generation)
      • 老年代(Old Generation/Tenured)
      • 永久代(Peramanent Generation)
    
    -XX:SurvivorRatio=n    //Edon区和Survivor区的占比(n/10)
    -XX:MaxTenuringThreshold=0    //设置垃圾最大年龄
    
    

    2. 年轻代

    • Eden (伊甸园)
      • 可以分为多个Thread Local Allocation Buffer


    • Survivor (S0/S1或者from/to)

      • Young GC发生时,整个年轻代进入其中一个Survivor区
    • 足够老的对象被提升到老年代(Tenured)

    3. 老年代

    • 老年代相对较大
    • 存储足够年老的对象
    • 发生GC的频率较低
      • 清除垃圾
      • 压紧内存


    永久代/元空间

    • Java 8之前:永久代
      • 堆的一部分
      • 存储类数据、字符串常量
      • OOM(OutOfMemory):Permgen space
        • 自定义Classloader
        • 动态字节码生成
      • Java 8+:元空间
        • 不是堆的一部分(-Xmx)
        • 除非特殊指定,否则没有上限
        • -XX:MaxMetaspaceSize/OOM:metaspace



    GC的种类

    • Minor GC/Young GC
      • 总是发生在Eden满的时候
      • 会发生STW

    - Major GC / Full GC - 这两个概念并没有明确的定义,这里阐述一般理解 - Major GC 清除老年代 - Full GC 清除整个堆


    Minor GC 的过早提升:有个对象占用空间非常大,但是年龄又没到 ,却过早提升到老年代 => 需要调整



    垃圾回收算法(Java 8)

    垃圾回收过程

    • -XX:+PrintGCDetails
    • -XX:+PrintGCDateStamps
    • -XX:+PrintGCTimeStamp,

    -XX:+DisableExplicitGC
    -XX:+PrintGCDetails
    -XX:+PrintGCApplicationStoppedTime
    -XX:+PrintGCApplicationConcurrentTime
    -XX:+PrintGCDateStamps
    -Xloggc:gclog.log
    -XX:+UseGCLogFileRotation
    -XX:NumberOfGCLogFiles=5
    -XX:GCLogFileSize=2000k

    >#### 让我们了解每个选项的目的。这些选项可能会因OS / JVM供应商/ JAVA版本而异。
    >
    >- DisableExplicitGC:默认情况下禁用此选项。有时,开发人员可能通过调用System.gc()或Runtime.getRuntime()。gc()实用地调用了垃圾回收。不建议这样做。因此,在生产系统中,我们启用此选项。这样就禁止了实用的垃圾回收调用。 
    >
    >- PrintGCDetails:默认情况下禁用此选项。如果启用此选项,则JVM将在每个垃圾收集中打印更多详细信息。
    >
    >- PrintGCApplicationStoppedTime:默认情况下禁用此选项。如果启用,它将在垃圾回收期间在应用程序暂停时打印信息。
    >
    >- PrintGCApplicationConcurrentTime:默认情况下,此选项处于禁用状态。如果启用,它将在GC期间打印有关应用程序运行时间的信息。
    >
    >- PrintGCDateStamps:默认情况下禁用此选项。如果启用,它将在每个GC上打印日期和时间详细信息。
    >
    >- loggc:这是一个字符串选项。我们必须传递gc日志文件名。在此文件中,我们将获取所有GC日志信息。
    >
    >- UseGCLogFileRotation:如果文件大小达到指定大小,则此选项指示JVM旋转日志文件。
    >
    >- NumberOfGCLogFiles:默认值为1。这设置轮换日志时要使用的文件数。
    >
    >- GCLogFileSize: 默认值为8KB。日志文件的大小,此时将旋转日志。
    >
    >通过设置以上选项,我们准备获取GC日志。要调整JVM,最好在负载测试期间启用这些选项,并在不同负载上获取GC日志以进行分析。从GC日志中,我们必须观察以下参数。
    >
    >#### 1. Young GC和Full GC多久发生一次?
    >GC事件之间应该有几分钟的时间间隔。如果Young GC发生的频率更高,那么我们可能需要查看分配的Young Gen空间。如果Full GC发生的频率更高,那么我们需要查看分配的堆大小。 
    >#### 2. 每个GC事件需要多少时间才能完成?
    >理想情况下,Young GC将花费几毫秒,而Full GC将花费几毫秒至几秒。在任何情况下,如果GC需要花费几秒钟到几分钟,那么我们必须查看堆大小的调整。如果GC线程花费更多时间来完成垃圾回收,则应用程序线程将处于等待状态(GC停止了world事件)。这会影响用户体验。
    
    <br><br><br><br><br>
    # 题外话
    ## Heap Dump
    Heap dump文件是一个二进制文件,它保存了某一时刻JVM堆中对象使用情况。Heap Dump文件是指定时刻的Java堆栈的快照,是一种镜像文件。Heap Dump一般都包含了一个堆中的Java Objects, Class等基本信息。同时,当你在执行一个转储操作时,往往会触发一次GC,所以你转储得到的文件里包含的信息通常是有效的内容(包含比较少,或没有垃圾对象了) 。我们可以这么理解:heap dump记录内存信息的,thread dump是记录CPU信息的。
    
    ## Heap Dump 包含的信息
    - 所有的对象信息
    对象的类信息、字段信息、原生值(int, long等)及引用值
    - 所有的类信息
    类加载器、类名、超类及静态字段
    - 垃圾回收的根对象
    根对象是指那些可以直接被虚拟机触及的对象
    - 线程栈及局部变量
    包含了转储时刻的线程调用栈信息和栈帧中的局部变量信息
    ## Heap Dump 获取方式
    使用 jmap 命令生成 dump 文件
    ```jmap -dump:live,format=b,file=c:dumpheap.hprof <pid>```
  • 相关阅读:
    【leetcode】1215.Stepping Numbers
    【leetcode】1214.Two Sum BSTs
    【leetcode】1213.Intersection of Three Sorted Arrays
    【leetcode】1210. Minimum Moves to Reach Target with Rotations
    【leetcode】1209. Remove All Adjacent Duplicates in String II
    【leetcode】1208. Get Equal Substrings Within Budget
    【leetcode】1207. Unique Number of Occurrences
    【leetcode】689. Maximum Sum of 3 Non-Overlapping Subarrays
    【leetcode】LCP 3. Programmable Robot
    【leetcode】LCP 1. Guess Numbers
  • 原文地址:https://www.cnblogs.com/pipemm/p/12489301.html
Copyright © 2020-2023  润新知