JVM-GC 相关知识

问题1:什么是JVM?

问题2:JVM的内存区是如何划分的?(运行时数据区)


JVM 运行时数据区:堆、栈、方法区(JDK8之前是 永久代实现的,之后就是元空间了)、程序计数器。其中堆和方法区是线程共享数据。

在Java虚拟机规范中的描述是:所有的对象实例 以及数组 都要在上分配。

是垃圾回收管理器管理的主要区域。

GC: 垃圾回收机制

1、什么是垃圾回收机制(什么是GC?)

程序在运行的时候会产生大量的内存垃圾,为了确保运行是的性能,JVM在程序运行过程中,不断的进行自动的垃圾回收(GC)。

1.1 什么是"垃圾"?

一些没有引用指向的内存对象都属于内存垃圾,因为这些对象已经无法被访问到了,程序用不了他们了,对程序而言,他们已经死亡。

总结:程序中不再被任何存活对象引用的对象。


2、什么是GC Roots

对象可达性的起点:

  • 虚拟机栈中的局部变量引用
  • 本地方法栈中的JNI引用的对象
  • 方法区中的静态变量引用
  • 方法区中常量引用
  • 所有被同步锁持有的对象
  • JVM内部引用(如系统类加载器)

3、垃圾判定算法

引用计数法(不推荐使用)

  • 原理:每个对象维护一个引用计数器,引用增减时更新计数器。计数器=0时判定为垃圾
  • 缺点:无法解决循环引用问题(A->B ,B->A)。

可达性分析算法

  • 原理:从 GC Roots 出发,遍历所有引用链。不在引用链上的对象即为垃圾。
  • 步骤:
    • 1、枚举所有GC Roots。
    • 2、递归标记所有可达对象
    • 3、清除所有未标记的对象(或将其回收)。

4、垃圾回收算法

标记-清除

  • **过程:**标记存活对象 -> 清除未标记对象。
  • 缺点: 内存碎片化,效率低(需要扫描全堆)
  • **适用场景:**老年代回收(如:CMS的并发标记阶段)

复制算法

  • **过程:**将内存分为两块(如 From / To)。将存活的对象复制到To区 -> 清空From区。
  • **缺点:**内存利用率低(需要保留一半空闲空间)
  • **优点:**无内存碎片、效率高(仅扫描存活对象)
  • **适用场景:**年轻代回收(如:Minor GC )

标记-整理

  • **过程:**标记存活对象 -> 将对象移动到一端 -> 清理边界外的内存
  • **优点:**无碎片。内存利用率高
  • **缺点:**移动对象开销大(需要新引用地址)
  • **适用场景:**老年代回收(如:Serial Old、Parallel Old)。

分代收集(重点)

  • 核心思想:对不同代使用不同算法
    • 年轻代:对象死亡率高 -> 复制算法(高效)
    • 老年代:对象存活率高 -> 标记-清除 或 标记-整理 (减少复制开销)。

5、堆内存模型与分代设计

Young Generation 年轻代

  • Eden 区(伊甸园)
    • 新创建的对象都会分配到Eden区(一些大对象特殊处理)。
  • Survivor(辛存者)
    • From-S0
    • To-S1
  • 分配比例:(Eden)8:(S0)1:(S1)1

Old Generation 老年代

MetaSpace 元空间

  • 以后会出一篇专门的文章说这个事(JDK 8 后元空间 取代了永久代
  • 如果感兴趣可以去了解:什么是永久代、永久代的缺点、永久代被替换的原因、元空间特点、元空间内存查看分析方法(以后的文章也是围绕这几点讲的)

6、核心回收流程(以分代收集为例)

对象分配

  • 新对象 --> Eden区
  • 大对象 --> 直接进入老年代
    • 大对象是我们设置 : -XX:PretenureSizeThreshold

Minor GC 触发条件

  • Eden区满时触发,执行过程
    • 在GC开始的时候,对象只会存在Eden区和名为"From-S0"区,"To-S1"区是空的。
    • 紧接着进行GC,Eden区中所有存活的对象都会被复制到To-S1区,
    • 在From-S0区中仍然存活的对象会根据年龄决定去向: 年龄达到一定值的对象会被移动到老年代中。没有达到阈值的对象会被复制到To-S1区
      • 年龄阈值:XX:MaxTenuringThreshold设置
    • 经过这次GC后,Eden区和From-S0区已经被清空。
    • From-S0 和 To-S1 会交换他们的角色,也就是新的To-S1就是上次GC前的Form-S0,不管怎么样,都会使To-S1是空的。

对象晋升规则

  • 年龄阈值:XX:MaxTenuringThreshold=15(默认)
  • 动态判定:当某年龄对象大小 > Survivor区50% -----> 大于等于该年龄的对象集体晋升

Major GC / Full GC 触发

  • 老年代空间不足
  • 元空间不足
  • 显示调用 System.gc()
相关推荐
猿小蔡-Cool4 小时前
Android Studio Memory Monitor内存分析核心指标详解
android·java·jvm
啊阿狸不会拉杆12 小时前
《Java 程序设计》第 12 章 - 异常处理
java·开发语言·jvm·python·算法·intellij-idea
wa的一声哭了14 小时前
Python多进程并行multiprocess基础
开发语言·jvm·人工智能·python·机器学习·语言模型·自然语言处理
hardStudy_h14 小时前
字节序详解
jvm
啊阿狸不会拉杆15 小时前
《Java 程序设计》第 11 章 - 泛型与集合
java·开发语言·jvm·数据结构·算法
张人玉1 天前
c#抽象类和接口的异同
java·jvm·c#
笑衬人心。1 天前
对象的创建过程
java·jvm
Joker—H1 天前
【Java】JVM虚拟机(java内存模型、GC垃圾回收)
java·开发语言·jvm·经验分享·个人开发·gc
极客BIM工作室1 天前
C++异常捕获:为何推荐按引用(by reference)捕获?
java·jvm·c++