JVM GC 垃圾回收

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 【1月更文挑战第3天】JVM GC 垃圾回收

1.GC简介:

JVM中的Garbage Collection,简称GC,它会不定时去堆内存中清理不可达对象。

2.GC分类:

 JVM在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代。因此GC按照回收的区域又分了两种类型,一种是普通GC(minor GC),一种是全局GC(major GC or Full GC)

新生代GCminor GC):只针对新生代区域的GC

老年代GCmajor GC or Full GC):针对老年代的GC,偶尔伴随对新生代的GC以及对永久代的GC

Minor GC触发机制:当年轻代满时就会触发Minor GC,这里的年轻代满指的是Eden满,Survivor满不会引发GC

Full GC触发机制:当年老代满时会引发Full GC,Full GC将会同时回收年轻代、年老代,当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载

Minor GC是对新生代进行的垃圾回收,它通常发生在Eden区满了时。在Minor GC中,虚拟机会回收年轻代的内存,清理掉不再被引用的对象,并将存活的对象移动到Survivor区或者老年代。

而Full GC是对整个堆内存(包括新生代和老年代)的垃圾回收。它会检查和清理整个堆内存中的无效对象,并进行内存整理,以便提供更大的连续可用空间。Full GC的触发条件比较复杂,可能包括老年代空间不足、永久代空间不足(在JDK8及以前的版本中)、元空间不足(在JDK8及以后的版本中),或者手动调用System.gc()方法等。

Full GC相比Minor GC通常需要更长的时间,因为它需要扫描和整理整个堆内存。执行Full GC时,应用程序一般会暂停,可能会导致一定的性能问题和延迟。

在实际开发中,我们需要根据应用的特点和性能需求来选择合适的垃圾回收策略。合理配置垃圾回收参数,如堆大小、新生代与老年代的比例、内存分配速率等,可以优化应用的性能和内存利用率。

3.GC的工作特点:

在GC工作中,通过某种算法来对JVM中的内存区域进行检测,对检测到的不可达对象,进行垃圾回收。

理论上GC过程中会频繁收集Young区,很少收集Old区,基本不动Perm区(元空间/方法区)。

4.标记不可达到对象:

引用计数法:

引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到循环指向的存在

首先需要声明,至少主流的Java虚拟机里面都没有选用引用计数算法来管理内存。

什么是引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器值减1.任何时刻计数器值为0的对象就是不可能再被使用的。

主流的java虚拟机中没有使用引用计数法的最主要的原因是它很难解决对象之间相互循环引用的问题。

public class MyObject {
  public Object ref;
  public String name;
  public static void main(String[] args) {
    MyObject myObject1 = new MyObject();
    MyObject myObject2 = new MyObject();
    myObject1.ref=myObject2;
    myObject2.ref=myObject1;
    myObject1=null;
    myObject2=null;
  }
}

将myObject1和myObject2赋值为null后,虚拟机依然无法回收,因为他们还相互指向和依赖。

可达性分析(GC ROOTS算法):

根搜索算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

简单理解,可以理解为堆外指向堆内的引用。

以下对象可以选取GC ROOTS节点:

(1). 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。

(2). 方法区中的类静态属性引用的对象。

(3). 方法区中常量引用的对象。

(4). 本地方法栈中JNI(Native方法)引用的对象。

5.垃圾回收的三种方式:

当标记完所有的存活对象时,我们便可以进行死亡对象的回收工作了。主流的基础回收方式可分为三种。

清除:

第一种是清除(sweep),即把死亡对象所占据的内存标记为空闲内存,并记录在一个空闲列表(free list)之中。当需要新建对象时,内存管理模块便会从该空闲列表中寻找空闲内存,并划分给新建的对象。

清除这种回收方式的原理及其简单,但是有两个缺点。一是会造成内存碎片。由于 Java 虚拟机的堆中对象必须是连续分布的,因此可能出现总空闲内存足够,但是无法分配的极端情况。另一个则是分配效率较低。如果是一块连续的内存空间,那么我们可以通过指针加法(pointer bumping)来做分配。而对于空闲列表,Java 虚拟机则需要逐个访问列表中的项,来查找能够放入新建对象的空闲内存。

压缩:

第二种是压缩(compact),即把存活的对象聚集到内存区域的起始位置,从而留下一段连续的内存空间。这种做法能够解决内存碎片化的问题,但代价是压缩算法的性能开销。

复制:

第三种则是复制(copy),即把内存区域分为两等分,分别用两个指针 from 和 to 来维护,并且只是用 from 指针指向的内存区域来分配内存。当发生垃圾回收时,便把存活的对象复制到 to 指针指向的内存区域中,并且交换 from 指针和 to 指针的内容。复制这种回收方式同样能够解决内存碎片化的问题,但是它的缺点也极其明显,即堆空间的使用效率极其低下。

总结:

回收死亡对象的内存共有三种方式,分别为:会造成内存碎片的清除性能开销较大的压缩以及堆使用效率较低的复制。当然,现代的垃圾回收器往往会综合上述几种回收方式,综合它们优点的同时规避它们的缺点。

相关文章
|
25天前
|
算法 Java
JVM垃圾回收机制
JVM垃圾回收机制
15 0
|
1月前
|
Java 程序员
探讨JVM垃圾回收机制与内存泄漏
探讨JVM垃圾回收机制与内存泄漏
|
2月前
|
算法 Java 关系型数据库
掌握这3个技巧,你也可以秒懂JAVA性能调优和jvm垃圾回收
JVM 是一个虚拟化的操作系统,类似于 Linux 和 Window,只是他被架构在了操作系统上进行接收 class 文件并把 class 翻译成系统识别的机器码进行执行,即 JVM 为我们屏蔽了不同操作系统在底层硬件和操作指令的不同。
24 0
|
2月前
|
存储 缓存 算法
JVM的垃圾回收机制
JVM的垃圾回收机制
|
3月前
|
算法 Java
太狠了!阿里技术专家撰写的电子版JVM&G1 GC实战,颠覆了传统认知
JVM是Java语言可以跨平台、保持高发展的根本,没有了 JVM, Java语言将失去运行环境。针对 Java 程序的性能优化一定不可能避免针对JVM 的调优,随着 JVM 的不断发展,我们的应对措施也在不断地跟随、变化,内存的使用逐渐变得越来越复杂。所有高级语言都需要垃圾回收机制的保护,所以 GC 就是这么重要。
|
3月前
|
算法 Java
JVM GC和常见垃圾回收算法
JVM GC和常见垃圾回收算法
48 0
|
15天前
|
存储 前端开发 安全
JVM内部世界(内存划分,类加载,垃圾回收)(上)
JVM内部世界(内存划分,类加载,垃圾回收)
49 0
|
19天前
|
存储 缓存 算法
深度解析JVM世界:垃圾判断和垃圾回收算法
深度解析JVM世界:垃圾判断和垃圾回收算法
|
1月前
|
Java Serverless 对象存储
Serverless 应用引擎常见问题之jvm在进行垃圾回收的时候会导致重启如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
22 0
|
1月前
|
存储 算法 Java
Go语言GC(垃圾回收)的工作原理
【2月更文挑战第23天】
28 0

热门文章

最新文章

  • 1
    Serverless 应用引擎产品使用之在函数计算中,数据库访问失败如何解决
    6
  • 2
    Serverless 应用引擎产品使用之在阿里云函数计算中发现没有NAC(Native Application Component)选项,且无法自己上传MOD(模块)如何解决
    7
  • 3
    Serverless 应用引擎操作报错合集之在阿里云函数计算中,调用了FC函数但是没有执行或者报错,并且在FC函数后台也看不到调用记录日志如何解决
    7
  • 4
    Serverless 应用引擎操作报错合集之在阿里函数计算中,sd部署启动报错CAExited 报错信息“operation not permitted”如何解决
    5
  • 5
    Serverless 应用引擎操作报错合集之在阿里函数计算中,SD Controlnet Depth 运行过程中出现错误“urllib3 v2.0 only supports OpenSSL 1.1.1+”如何解决
    7
  • 6
    Serverless 应用引擎操作报错合集之在阿里云函数计算中,laravel zip包使用示例的start.sh脚本启动时出现错误代码如何解决
    7
  • 7
    Serverless 应用引擎操作报错合集之在阿里云函数计算中,服务器调用FC函数时出现 "[Errno -3] Temporary failure in name resolution)" 错误如何解决
    5
  • 8
    Serverless 应用引擎操作报错合集之在Serverless 应用引擎中,部署过程中遇到错误代码如何解决
    9
  • 9
    Serverless 应用引擎操作报错合集之在 Serverless 应用引擎中,遇到“没法通过 head 传递灰度标识”如何解决
    8
  • 10
    Serverless 应用引擎操作报错合集之在阿里函数计算中,函数执行超时,报错Function time out after如何解决
    12