垃圾回收(GC)的核心知识点总结

1.为什么要有垃圾回收?

**避免内存泄漏:**在手动内存管理的系统中,程序员需要显式地分配和释放内存。如果程序员犯了错误,忘记释放内存,就会导致内存泄漏,使程序占用的内存不断增加,最终耗尽系统资源。

**提高开发效率:**垃圾回收允许程序员专注于解决业务问题,而无需担心手动内存管理。这提高了开发效率,减少了错误的可能性。

减少程序错误:手动内存管理容易导致各种内存错误,如空指针引用、野指针等。垃圾回收可以减少这些类型的错误。

**提高程序的可维护性:**垃圾回收可以减少内存管理方面的代码,使代码更易于维护和理解。

2.垃圾回收主要回收哪个内存区域?

在JVM中内存区域划分为:程序计数器,栈(Java虚拟机栈,本地方法栈),方法区,堆。
对于一个Java进程只有一份堆与方法区,而程序计数器与栈则每一个Java线程都有一份。
其中栈内存放的主要是局部变量,出了作用域也就销毁了,不需要GC。
堆中存放的主要是new出来的对象,也是GC的主要工作区域。

3.标记的过程

**根对象标记:**标记过程通常从根对象开始,根对象包括全局变量、活动线程的调用栈中的局部变量以及其他直接可访问的对象。这些根对象被认为是程序的起点,垃圾回收器从这些对象开始遍历。

**可达性分析:**从根对象出发,垃圾回收器通过遍历对象之间的引用链来确定可达的对象。如果某个对象可以通过一系列引用链从根对象访问到,那么它被标记为可达,表示它仍然在使用中。这个过程通常使用深度优先搜索或广度优先搜索等算法进行。

**未标记对象:**未被标记的对象被认为是不可达的,即它们不再被程序引用,因此可以被回收。这些对象的内存可以被释放以供将来的对象分配使用。

**标记清除:**一旦所有可达对象都被标记,垃圾回收器就会清除未标记的对象。这通常涉及将这些对象的内存释放回可用内存池,以供程序后续的内存分配使用。

**内存整理(可选):**一些垃圾回收算法(如标记-整理算法)可能在标记清除后执行内存整理。这个过程可以将可用内存合并成更大的块,减少内存碎片,提高内存分配的效率。

4.回收的过程

**标记(Marking):**在标记阶段,垃圾回收器标识出程序中不再可达的对象。这通常从根对象开始,通过遍历引用链来确定哪些对象仍然可以被访问。可达对象被标记为存活,而不可达对象被标记为待清理。

**清除(Sweeping):**清除阶段是垃圾回收的核心步骤。在这个阶段,垃圾回收器遍历内存中的对象,将未标记的对象(即垃圾)释放或回收。这些对象的内存被标记为可重用。

**内存整理(Optional):**某些垃圾回收算法,如标记-整理算法,可能在清除后执行内存整理。这个过程有助于减少内存碎片,使内存分配更加高效。

**压缩(Compacting):**某些垃圾回收算法,如分代垃圾回收,可能会包括内存压缩。在这个过程中,存活的对象被移动到内存的一端,以减少碎片并提高内存分配的效率。

**回收资源:**在清除和整理之后,垃圾回收器释放了不再使用的内存资源,使它们可用于将来的内存分配。

不同的编程语言和运行时环境使用不同的垃圾回收算法,如标记-清除、标记-整理、分代垃圾回收等,以满足不同应用程序的需求。这些算法的实现细节可能有所不同,但它们的核心目标都是识别和释放不再使用的内存,以减少内存泄漏和内存溢出问题。

5.垃圾回收器有哪些典型实现?

**分代垃圾回收器(Generational Garbage Collection):**

分代回收的工作进程:

1.堆内存为两个区:新生代和老年代

2.新生代默认占堆内存的三分之一,老年代默认占三分之二

3.新生代又分Eden区.Survior From区,Survivr To区.默认比例是8:1:1

4.工作过程

所有新创建的对象都在Eden区,当Eden区内存满后将Eden区+Survior From区存活的对象复制到Survior To区

清空Eden区和Survivor From区

同时Survivor To和Survivor From区进行交换

每次Minor GC存活对象年龄加1,当年龄到达15岁时,被移到老年代

当Eden的空间无法容纳新创建的对象时,这些对象直接被移到老年代

当老年代空间占用达到阈值时触发Major GC

以上流程循环执行

你可能感兴趣的:(JVM,JVM)