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%)
相关文章
|
23天前
|
存储 算法 Java
散列表的数据结构以及对象在JVM堆中的存储过程
本文介绍了散列表的基本概念及其在JVM中的应用,详细讲解了散列表的结构、对象存储过程、Hashtable的扩容机制及与HashMap的区别。通过实例和图解,帮助读者理解散列表的工作原理和优化策略。
30 1
散列表的数据结构以及对象在JVM堆中的存储过程
|
9天前
|
监控 算法 Java
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
4天前
|
机器学习/深度学习 监控 算法
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
19 1
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
72 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
1天前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
8 0
|
2月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
57 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
2月前
|
算法 Java
谈谈HotSpot JVM 中的不同垃圾回收器
【10月更文挑战第5天】理解 HotSpot JVM 中的不同垃圾回收器(如 CMS、G1 和 ZGC)的区别,需要深入了解它们的设计原理、工作方式和应用场景。以下是对这三个垃圾回收器的简要概述以及一个示例 Java 程序,虽然示例程序本身不能直接展示垃圾回收器的内部机制,但可以帮助观察不同垃圾回收器的行为。
27 1
|
3月前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
117 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
2月前
|
算法 Java
JVM进阶调优系列(3)堆内存的对象什么时候被回收?
堆对象的生命周期是咋样的?什么时候被回收,回收前又如何流转?具体又是被如何回收?今天重点讲对象GC,看完这篇就全都明白了。