聊聊java虚拟机中的垃圾收集器

     2022-03-29     197

关键词:

前言

JAVA虚拟机的垃圾收集器是虚拟机内存的清道夫,它的存在让JAVA开发人员能将更多精力投入到业务研发上。了解垃圾收集器,并利用好这个工具,能更好的保障服务稳定性。这篇文章通过分析JAVA虚拟机内存模型,介绍垃圾收集器常用算法和收集器类别,使得垃圾收集器的配置和使用变得不再遥不可及。

JAVA虚拟机内存模型

JAVA虚拟机内存可以划分为:虚拟机栈、本地方法栈、JAVA堆内存、方法区(包含运行时常量池)、程序计数器、直接内存。

虚拟机栈

虚拟机栈是线程私有的,生命周期跟线程相同。也就是说一个线程被创建后,虚拟机为其分配了一个独立的栈帧来存储线程的局部变量、操作数、动态链接、方法出口等信息,当线程结束后,该栈帧也会被回收清理。

本地方法栈

本地方法栈是虚拟机的native方法执行期间使用的一个栈帧。

JAVA堆内存

堆内存是被所有线程共享的一块区域,用来存放对象实例和数组,属于内存中最大的一块区域,也是垃圾收集的主要区域。从垃圾收集的角度看,堆内存经常分为新生代和老年代。

方法区

方法区也是被所有线程共享的一块区域,用来存储被虚拟机加载的类信息、常量、静态变量、JIT编译后代码等数据。也可以成为永久代。

程序计数器

程序计数器是线程私有的,作为当前线程所执行的字节码的行号指示器,每个线程有一个程序计数器,用于记录CPU切换线程时记录当前线程的执行位置,以便下次继续从当前位置往下执行。

直接内存

这块不属于JAVA虚拟机内存,但使用频繁,也可称之为“堆外内存”

JAVA虚拟机垃圾收集器

根据上述对JAVA虚拟机内存区域模型的介绍,我们知道JAVA程序中的对象实例都存储在JAVA堆内存中,因此垃圾收集主要也是针对堆内存进行。为了更好的管理JAVA对象实例,并结合对象实例的生存时间长短,JAVA虚拟机将堆内存分为新生代和老年代,分别存储刚创建不久的对象和存活较长时间的对象实例,并采用分代收集的策略分别回收新生代和老年代的内存。

内存分配与回收策略

  • 1、 分代收集思路。根据JAVA对象的生存周期特点,虚拟机将堆内存分为新生代和老年代,并分别采用新生代和老年代的垃圾回收策略。
  • 2、 新生代细分为Eden区和两个Survivor区(即From区和To区)。大多数新生对象创建频繁,且存活时间短,为了提高新生代区域垃圾收集效率,新创建的对象存放在Eden区,当Eden区快满的时候,虚拟机对其触发一次Minor GC,将新生代存活对象移动到From区,原来From区的对象根据存活年龄决定放到To区还是老年代,然后清空Eden区和From区,接着将To区对象全部移到From区。
  • 3、 大对象直接进入老年代,可以配置新生代对象的最大值,对象超过这个值就直接进入老年代。
  • 4、 发起Minor GC前,会先判断老年代最大可用连续空间是否大于新生代对象占用的空间,如果小于或不允许冒险,则触发一次Full GC。

    垃圾收集算法(3种基本算法)

  • 1、 复制算法。针对于新生代的垃圾收集算法。当新生代Eden区快满的时候,将Eden区对象复制到From区,将From区对象根据存活年龄决定复制到To区还是到老年代,然后清除Eden区和From区,接着将To区对象复制到From区。
  • 2、 标记-清除算法。垃圾收集算法标记出需要回收的对象,标记完成后直接统一回收。垃圾收集器使用可达性分析来判断哪些对象是否存活,通过设置一系列GC Roots节点(包括栈、方法区中的静态属性和常量所引用的对象,以及本地方法栈中引用的对象),从这类节点往下搜索,当对象不在GC Root节点的引用链上时,说明对象不可达,可以被回收。
  • 3、 标记-整理算法。垃圾收集算法标记出需要回收的对象,标记完成后将存活对象往内存的一端移动,然后直接清理掉端边界以外的内存。

    常用垃圾收集器

    由于虚拟机中的垃圾收集是分代收集的,新生代和老年代的垃圾收集策略不太一样,所以一般是使用针对新生代和老年代的垃圾收集器组合。

  • 1、 Serial GC。新生代收集器,采用复制算法,用于Client客户端新生代垃圾收集,针对内存占用较少的应用进行垃圾收集。
  • 2、 Serial Old GC。老年代收集器,采用标记-整理算法,用于Client客户端老年代垃圾收集,针对内存占用较少的应用进行垃圾收集。
  • 3、 Parallel Scavenge GC。新生代收集器,采用复制算法,并行收集新生代内存垃圾,可以设置垃圾收集器的吞吐量,还可以设置自动适配调节吞吐量。
  • 4、 Parallel New GC。新生代收集器,采用复制算法,并行收集新生代内存垃圾。
  • 5、 Parallel Old GC。老年代收集器,采用标记-整理算法,并行收集老年代内存垃圾。
  • 6、 CMS GC。老年代收集器,采用标记-清除算法,并行收集老年代内存垃圾,不整理内存。由于在执行垃圾收集期间不中断业务线程,所以容易产出“浮动垃圾”,导致Full GC。可以通过设置参数来触发内存整理任务。
  • 7、 G1 GC。不再将堆内存区分新生代和老年代,而是将堆内存看作若干个均分小区域,并对最空闲的内存区域进行标记和回收。适用于大内存的应用。

java虚拟机垃圾回收机制

...ava虚拟机中,对象和数组的内存都是在堆中分配的,垃圾收集器主要回收的内存就是再堆内存中。如果在Java程序运行过程中,动态创建的对象或者数组没有及时得到回收,持续积累,最终堆内存就会被占满,导致OOM。JVM提供了... 查看详情

如何修改jvm虚拟机垃圾回收器

参考技术A垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法、火车算法)的具体实现,不同商家、不同版本的JVM所提供的垃圾收集器可能会有很在差别,本文主要介绍HotSpot虚拟机中的垃圾收集器。本回答... 查看详情

垃圾收集器和内存分配策略

1.概述  为什么虚拟机要进行垃圾回收?    因为Java虚拟机中的内存是有限的,在程序运行中无时无刻不在创建对象,消耗内存,如果不对内存进行回收,就无法解决内存不足的问题,自然程序无法运行持久。  如今内... 查看详情

gc回收方法区

很多人认为方法区(或者hotSpot虚拟机中的永久代)是没有垃圾收集的,java虚拟机规范中确实说过不要求虚拟机在方法区实现垃圾收集,而且在方法区中进行垃圾收集的“性价比”一般比较低:在堆中,尤其是新生代中,常规应... 查看详情

垃圾收集器

概括:Serial收集器:用于新生代,采用复制算法,单线程收集器,它在垃圾收集时,必须暂停其他所有的工作线程。是虚拟机运行在Client模式下的默认新生代收集器。优点:简单高效。  ParNew收集器:用于新生代,采用复制算... 查看详情

垃圾收集器与内存分配策略之篇二:垃圾收集器

五、垃圾收集器  如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。由于java虚拟机规范对垃圾收集器实现没有任何的规范因此不同的厂商,不同的版本的虚拟机所提供的垃圾收集器都有可... 查看详情

jvm垃圾回收-7种垃圾收集器

概述垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法)的具体实现,不同商家、不同版本的JVM所提供的垃圾收集器可能会有很在差别,本文主要介绍HotSpot虚拟机中的垃圾收集器。7种垃圾收集器如图所示... 查看详情

java虚拟机-垃圾回收(代码片段)

...你厉害的人都在努力,你还有什么理由不努力。垃圾收集器(GarbageCollection,简称GC),垃圾收集需要完成的三件事情:·哪些内存需要回收?·什么时候回收?·如何回收?1.那如何判断对象是否... 查看详情

《深入理解java虚拟机》读后笔记-垃圾收集算法

文章目录《深入理解Java虚拟机》读后笔记-垃圾收集算法1.概述2.如何判断对象已死?2.1引用计数算法2.2可达性分析算法2.3Java中的引用2.4回收方法区3.垃圾收集算法3.1分代收集理论3.2标记-清除算法3.3标记-复制算法3.4标记-整理... 查看详情

jvm垃圾收集器

??本文讲述的是HotSpot虚拟机中的垃圾收集器。下图展示了7种不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。Serial收集器单线程,只会使用一个CPU或者一条收集线程去完成垃圾收集工作。进行垃圾... 查看详情

高频面试题-请把java垃圾回收器说清楚!

...#xff1a;如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。不同的时代,出现了不同了垃圾收集器,它们被不断的应用在各个版本的Java虚拟机中。首先来画一张图,将具体的几个垃圾... 查看详情

深入java虚拟机之垃圾收集

前言:说起垃圾收集器,JAVA开发者肯定是听得耳朵都起茧子了。如果让你设计一个JAVA垃圾收集器,那么你关注那些点呢?//1.哪些内存需要回收?//2.什么时候回收?//3.如何回收?这篇博文就是记录这些问题答案的。闲言碎语不... 查看详情

java虚拟机:垃圾回收策略及算法

java虚拟机中的程序计数器区、虚拟机栈区、本地方法栈区3个区域是随着线程的创建而创建,随着线程的结束而结束时,内存自然得到回收,所以这三个区域不需要过多考虑内存的回收问题。java虚拟机中的方法区和虚拟机堆区2... 查看详情

java虚拟机之垃圾收集器与内存分配策略

  哪些内存需要回收?    java内存运行时区域的各个部分,其中程序计数器,虚拟机栈,本地方法栈3个区域随线程而生,随线程而灭,栈中的栈帧随着方法的进入和退出而有条不絮的执行着出栈和入栈操作。每一个栈帧... 查看详情

jvm虚拟机——垃圾收集算法

...m/leesf456/p/5218594.html1.哪些内存需要进行垃圾回收  对于虚拟机中线程私有的区域,如程序计数器、虚拟机栈、本地方法栈都不需要进行垃圾回收,因为它们是自动进行的,随着线程的消亡而消亡,不需要我们去回收,比如栈的... 查看详情

深入理解java虚拟机垃圾收集器与内存分配策略

一、根搜索算法:    (1)定义:通过一系列名为"GCRoots"的对象作为起点,从这些起点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GCRoots没有任何引用链相连的时候,则证明此对象不可用  (2)GCRoots对象包括这... 查看详情

垃圾回收的原理了解下?

...问题,也不需要像C程序员那样战战兢兢。这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制。概括地说,该机制对JVM(JavaVirtualMachine)中的内存进行标记,并 查看详情

java垃圾回收garbagecollection(垃圾收集器

垃圾收集器HotSpot虚拟机的垃圾收集器  Java虚拟机规范中对垃圾收集器如何实现没有任何规定,因此不同版本的虚拟机所提供的垃圾收集器都可能有很大的差别,并且都会提供参数供用户自己应用的特点和要求组合出各个年代... 查看详情