美文网首页
JVM内存分析与入门实践

JVM内存分析与入门实践

作者: CoderInsight | 来源:发表于2023-10-07 15:48 被阅读0次

    (1),JVM内存分配机制

    1),新生代

    1. 在java中新创建的对象一般会放在新生代的Eden,经过Minor GC之后没有被销毁的对象会被复制到新生代的Survivor区域。
    2. 通过标记复制的方式实现Survivor区域的 From SurvivorTo Survivor

    2),老年代

    只要满足以下几种情况的一种就会由新生代进入老年代:

    1. 经过了15次Minor GC之后,当前对象还是没有销毁;
    2. 动态对象年龄判断;
    3. 大对象直接进入老年代!!!
    4. Minor GC之后的对象太多,导致Survivor区无法放下;
    5. 老年代空间分配担保原则;

    3),名词解释

    ![[11196780-5f83c29d19bc09c6.webp]]

    (2),JVM的两种GC机制

    1),Minor GC

    发生在新生代的垃圾回收动作,比较频繁,回收速度快。

    2),Major GC/Full GC

    发生在老年代的GC,速度比较慢。

    (3),JVM内存结构

    1),堆内存(Heap Space)

    1. 堆内存是JVM的主要部分,由新生代(1/3)、老年代(2/3)组成。
    2. 堆分为两种,一种深堆:指的是对象本身的大小,如果是集合、数组,则是其所有元素的和;另一种是浅堆:指的则是(对象本身的大小 + 引用其他对象的大小),其更能准确的反应出一个对象实际占用的大小。
    3. 判断对象是否存活,可以通过 GC Root 的引用链(Reference Chain),当一个对象在GCRoot上无用了则对象不可达。可以在MAT中使用 Path to Gc Roots 进行查看。

    2),方法区(Method Area/PermGen)

    存储类信息、常量、静态变量等数据。

    3),栈(Native Area)

    1. 主要是用于方法的执行、栈引用的对象、JNI调用的对象。
    2. Queue(队列)是先进先出,而Stack(栈)则是先进后出。

    (4),常见GC算法

    1),串行GC、并行GC

    1. 无论是串行 GC、还是并行GC ,他们对年轻代使用 mark-copy(标记—复制)算法,对老年代使用 mark-sweep-compact(标记—清除—整理)算法。他们的区别是串行GC只能使用单个核心;而串行GC在执行 “标记和复制/整理” 阶段时使用多个线程。且无论年轻代和老年代的垃圾回收都会触发 STW 事件,暂停所有的应用线程来执行垃圾收集。
    2. JDK1.8默认使用的是并行GC,而 G1 成为 JDK9 以后版本的默认 GC 策略,同时 G1 算法是在jdk1.6的时候已经出现了,所以可以在 1.8 中通过配置参数指定。

    2),GMS垃圾收集器

    CMS GC 的官方名称为 Mostly Concurrent Mark and Sweep Garbage Collector(最大并发—标记—清除—垃圾收集器)。其对年轻代采用并行 STW 方式的 mark-copy(标记—复制)算法,对老年代主要使用并发 mark-sweep(标记—清除)算法。

    CMS GC 的设计目标是避免在老年代垃圾收集时出现长时间的卡顿,主要通过两种手段来达成此目标:

    • 第一,不对老年代进行整理,而是使用空闲列表(free-lists)来管理内存空间的回收。
    • 第二,在 mark-and-sweep(标记—清除)阶段的大部分工作和应用线程一起并发执行。

    3),G1垃圾收集器

    G1 的全称是 Garbage-First,意为垃圾优先,哪一块的垃圾最多就优先清理它。

    G1 GC 最主要的设计目标是:将 STW 停顿的时间和分布,变成可预期且可配置的。

    4),算法引用推荐

    1. 选择正确的 GC 算法,唯一可行的方式就是去尝试,并找出不合理的地方,一般性的指导原则:
      • 如果系统考虑吞吐优先,CPU 资源都用来最大程度处理业务,用 Parallel GC;
      • 如果系统考虑低延迟有限,每次 GC 时间尽量短,用 CMS GC;
      • 如果系统内存堆较大,同时希望整体来看平均 GC 时间可控,使用 G1 GC。
    2. 对于内存大小的考量:
      • 一般 4G 以上,算是比较大,用 G1 的性价比较高。
      • 一般超过 8G,比如 16G-64G 内存,非常推荐使用 G1 GC
    3. G1参数配置
      • -XX:+UseG1GC:启用 G1 GC;
      • -XX:+InitiatingHeapOccupancyPercent:决定什么情况下发生 G1 GC,G1 内部并行回收循环启动的阈值,默认为 Java Heap 的 45%。这个可以理解为老年代使用大于等于 45% 的时候,JVM 会启动垃圾回收。
      • -XX:MaxGCPauseMills:期望每次 GC 暂定的时间,比如我们设置为 50,则 G1 GC 会通过调节每次 GC 的操作时间,尽量让每次系统的 GC 停顿都在 50 上下浮动。如果某次 GC 时间超过 50ms,比如说 100ms,那么系统会自动在后面动态调整 GC 行为,围绕 50 毫秒浮动。

    参考连接

    1. 踩坑记录-maxHttpHeaderSize配置-内存都去哪儿
    2. JVM heap dump分析
    3. 14 常见的 GC 算法(ParallelCMSG1)

    相关文章

      网友评论

          本文标题:JVM内存分析与入门实践

          本文链接:https://www.haomeiwen.com/subject/oihvbdtx.html