zoukankan      html  css  js  c++  java
  • 今日份学习: 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>```
  • 相关阅读:
    腾讯云搭建web环境基础指导
    php正则表达式填坑
    微信小程序新手填坑
    如何优雅的扒网站——工具篇
    两个常见的前端问题:如何让分页码居中显示 及 解决浮动元素覆盖的问题
    非常全面的PHP header函数设置HTTP头的示例
    Nginx + fastcgi + php 的原理与关系
    Linux命令之 tar
    数据结构和算法
    单例模式
  • 原文地址:https://www.cnblogs.com/pipemm/p/12489301.html
Copyright © 2011-2022 走看看