JVM-垃圾回收,一个对象产生到灭亡的过程

简介: java中,内存运行时区域中的程序计数器、虚拟机栈、本地方法栈3个区域生命周期随着线程的生存而生存,而堆和方法区被各线程共享,这些占用空间而不被任何对象引用的对象,我们称之为垃圾(Garbage),而垃圾收集器(Garbage Collector)的工作即是通过一些列算法对这些垃圾进行清理。

前言

什么是垃圾

java中,内存运行时区域中的程序计数器、虚拟机栈、本地方法栈3个区域生命周期随着线程的生存而生存,而堆和方法区被各线程共享,这些占用空间而不被任何对象引用的对象,我们称之为垃圾(Garbage),而垃圾收集器(Garbage Collector)的工作即是通过一些列算法对这些垃圾进行清理。

分代收集算法

分代收集算法是基于JVM内存分代模型的一种算法,是目前大部分垃圾收集器都采用的算法,它的核心思想是根据对象存活的生命周期将内存划分为新生代和老年代,老年代的特点是每次垃圾回收时都只有少量的对象被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,可以根据不同的特点采取适合的回收算法。
在这里插入图片描述

一个对象产生到灭亡的过程

  1. 新产生的对象优先分配在Eden区。
  2. 当Eden区满了或放不下了进行GC,这时候其中存活的对象会复制到from区,如果from区放不下则会全部进入老年代,然后Eden内存全部清除。
  3. 之后产生的对象继续分配在Eden区,当Eden区又满了或放不下了,这时候将会把Eden区和from区存活下来的对象复制到to区(同理,如果存活下来的对象to区都放不下,则这些存活下来的对象全部进入年老代),之后回收掉Eden区和from区的所有内存。
  4. 如上这样,会有很多对象会被复制很多次(每复制一次,对象的年龄就+1),默认情况下,当对象被复制了15次(这个次数可以通过:-XX:MaxTenuringThreshold来配置),就会进入年老代了。
  5. 当年老代满了或者存放不下将要进入年老代的存活对象的时候,就会发生一次Full GC(这个是我们最需要减少的,因为耗时很严重)。

    如何确定垃圾

    哪些是垃圾?垃圾回收器进行垃圾回收前的第一个步骤就是确定哪些对象是存活的,哪些对象是被抛弃的,通过引用计数、根可达分析两种算法来确定。

    引用计数

    给对象添加一个引用计数器,每当一个对象引用时计数器+1,当引用失效时就-1,计数器为0时该对象就说明该对象不可用。

    • 优点:实现简单、效率高
    • 缺点:无法处理循环引用的对象,比如:a->b->c->a

根可达分析

以GC Roots为起点向下扫描,扫描所经过的路径称之为引用链,当一个对象不在引用链上,说明该对象不可用。
GC Roots定义:在JAVA语言中,存在虚拟机栈、本地方法栈、方法区、常量池等引用的对象。

  • 优点:精准、严谨,可解决循环引用的对象
  • 缺点:实现复杂,效率低。

如何回收垃圾

垃圾回收是在垃圾定位后的操作行为,常见的垃圾回收算法有:标记-清除、复制算法、标记压缩。

标记-清除

通过根可达算法标记被引用的对象即存活对象,未被标记的则为垃圾对象,然后对其清除。
其特点为:算法相对简单,需要扫描两遍空间(第一次 标记,第二次清除),清理后容易产生碎片。适用于存活对象多的情况(标记多,回收少),多为老年代。
在这里插入图片描述

复制算法

通过根可达算法标记所有存活的对象并将这些对象复制到另一块内存中,然后将之前的内存全部回收。
其特点为:需要一块空的内存去移动复制对象,调整对象的引用,只需扫描一次,清理后不会产生碎片,适用于存活对象少的情况(标记少,回收多),多为新生代。在这里插入图片描述

标记压缩

与标记-清除算法相似,不同的是在清除后再将存活的对象整理压缩在一起。
其特点优化了标记清除算法的碎片,因为需要移动对象,效率较低。
在这里插入图片描述

如何使用垃圾回收器

在这里插入图片描述

如图所示,图中展示了7种不同分代的收集器,在实际虚拟机中都是搭配使用,以达到最佳效果。

收集器 描述 算法
Serial 新生代单线程收集器,标记和清理都是单线程。 复制算法
Serial Old 老年代单线程收集器,Serial收集器的老年代版本。 标记-整理算法
ParNew 新生代收集器,可以认为是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。 复制算法
Parallel Scavenge 并行收集器,多个收集器线程同时工作,追求高吞吐量,高效利用CPU。 复制算法
Parallel Old Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先 复制算法
CMS 并发收集器,收集器线程与用户线程同时工作。高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高,响应时间快,停顿时间短,多核cpu 追求高响应时间的选择 三色标记+Incremental Update
G1 并发收集器,不存在分代,适用于不需要实现很高的吞吐量的场景 三色标记 +SATB

常用组合参数

  • -XX:+UseSerialGC =Serial New +Serial Old
  • -XX:+UseParNewGC =ParNew+Serial Old
  • -XX:+UseConcMarkSweepGC =ParNew+CMS+Serial Old
  • -XX:+UseParallelGC =Parallel Scavenge+Parallel Old

    GC常用参数

  • -Xmn(年轻代) -Xms(最小堆) -Xmx(最大堆) -Xss(栈空间)
  • -XX:+UseTLAB
  • -XX:+PrintTLAB
  • -XX:+TLABSize
  • -XX:+PrintGC
  • -XX:+PrintGCDetails
  • -XX:+PrintGCTimeStamps
  • -verbose:class (类加载详细过程)
  • -XX:+PrintFlagsFinal (最终参数). java -XX:+PrintFlagsFinal -version
  • -XX:+PrintCommandLineFlags (默认参数) java -XX:+PrintCommandLineFlags -version
  • -Xloggc:/path (GC日志路径)
  • -XX:+MaxTenuringThreshold (升代年龄 最大15)
  • -XX:+UseParallelGC
  • -XX:SurvivorRatio
  • -XX:+ParallelGCThreads (并行收集器的线程数,一般设为和CPU核数相同)
  • -XX:+UseAdaptiveSizePoliy (自动选择各区大小)
  • -XX:+UseConcMarkSweepGC
  • -XX:ParallelCMSThreads
  • -XX:CMSInitiatingOccupancyFraction (使用多少比例开始CMS收集,默认68%)
  • -XX:+UseG1GC
  • -XX:+MaxGCPauseMillis
  • G1NewSizePercent (新生代最小比例,默认为5%)
  • G1MaxNewSizePercent (新生代最大比例,默认为60%)
相关文章
|
1月前
|
存储 缓存 监控
Java面试题:在Java中,对象何时可以被垃圾回收?编程中,如何更好地做好垃圾回收处理?
Java面试题:在Java中,对象何时可以被垃圾回收?编程中,如何更好地做好垃圾回收处理?
34 0
|
1月前
|
存储 算法 Java
Java面试题:深入探究Java内存模型与垃圾回收机制,解释JVM中堆内存和栈内存的主要区别,谈谈对Java垃圾回收机制的理解,Java中的内存泄漏及其产生原因,如何检测和解决内存泄漏问题
Java面试题:深入探究Java内存模型与垃圾回收机制,解释JVM中堆内存和栈内存的主要区别,谈谈对Java垃圾回收机制的理解,Java中的内存泄漏及其产生原因,如何检测和解决内存泄漏问题
37 0
|
1月前
|
存储 算法 安全
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
39 0
|
20天前
|
存储 监控 算法
(六)JVM成神路之GC基础篇:对象存活判定算法、GC算法、STW、GC种类详解
经过前面五个章节的分析后,对于JVM的大部分子系统都已阐述完毕,在本文中则开始对JVM的GC子系统进行全面阐述,GC机制也是JVM的重中之重,调优、监控、面试都逃不开的JVM话题。
|
20天前
|
存储 缓存 算法
(五)JVM成神路之对象内存布局、分配过程、从生至死历程、强弱软虚引用全面剖析
在上篇文章中曾详细谈到了JVM的内存区域,其中也曾提及了:Java程序运行过程中,绝大部分创建的对象都会被分配在堆空间内。而本篇文章则会站在对象实例的角度,阐述一个Java对象从生到死的历程、Java对象在内存中的布局以及对象引用类型。
|
23天前
|
Java
Jinfo 查看 jvm 配置及使用 Jstat 查看堆内存使用与垃圾回收
Jinfo 查看 jvm 配置及使用 Jstat 查看堆内存使用与垃圾回收
29 5
|
23天前
|
存储 算法 Java
JVM 垃圾回收算法与垃圾回收器
JVM 垃圾回收算法与垃圾回收器
26 3
|
3天前
|
算法 Java 应用服务中间件
探索JVM垃圾回收算法:选择适合你应用的最佳GC策略
探索JVM垃圾回收算法:选择适合你应用的最佳GC策略
|
26天前
|
监控 Java 运维
开发与运维收集问题之jstat命令查看JVM垃圾回收情况如何解决
开发与运维收集问题之jstat命令查看JVM垃圾回收情况如何解决
14 1
|
20天前
|
弹性计算 运维 Java
Serverless 应用引擎使用问题之JVM进行垃圾回收时重启,该如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。