注:本文根据《深入理解Java虚拟机》第3章部分内容整理而成。
一.如何判断对象是否需要回收?
堆中几乎放着java世界中的所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象哪些还“存活”着,哪些已经“死去”(即不可能再被任何途径使用的对象)。而如何判断对象是否应该回收,存在两个算法:引用计数算法(Reference Counting)和根搜索算法(GC Roots Tracing) 。但是Java语言中没有选用引用计数算法来管理内存,主要的原因是它很难解决对象之间的相互循环引用的问题。所以下面我们主要介绍根搜索算法。
在Java和C#中都是使用根搜索算法判定对象是否存活。算法基本思路就是通过一系列的称为“GC Roots”的点作为起始进行向下搜索,当从GC到某一个对象不可达的时候,也就是说一个对象到GC Roots没有任何引用链相连的时候,这个对象就会被判定为可回收的。
在java中,可作为GC Roots的对象包括下面几种:
1.虚拟机栈(栈帧中的本地变量表)中的引用的对象。
2.方法区中的类静态属性引用的对象。
3.方法区中的常量引用的对象。
4.本地方法栈中JNI(即一般说的Native方法)引用的对象。
根搜索算法的图示如下:
图:根搜索算法判定对象是否可回收
二.垃圾收集算法
1.标记-清除算法(Mark-Sweep)
这是最基础的垃圾收集算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。它的主要缺点有两个:一个是效率问题,标记和清除效率都不高;另一个是空间问题,标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致分配大对象是没有足够的大的连续空间,而不得不提前触发另一次垃圾收集动作。
图:标记-清除算法示意图
2.复制算法(Copying)
为了解决效率问题,有了“复制”的算法,他将可用内存分为大小相同两块。每次只用一块,当一块空间用完了,就将还存活的对象复制到另一块上,然后将刚使用过的内存空间一次清理掉。这样使得每次都是对其中的一块进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况。实现简单,运行高效。只是这种算法的代价是将内存缩小到原来的一半,代价太贵了点。实际上,新生代中的对象98%都是朝生夕死,所以不需要按1:1的比例来分内存,而是将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden空间和其中一块Survivior空间。当回收时,将Eden和Survivor中还存活的对象一次性的拷贝到另一块Suivivior中,最后清理掉Eden和刚用过的Survivor空间。
图:复制算法示意图
3.标记-整理(Mark-Compact)
复制收集算法在对象存活率高的时候就要执行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保用于应付半区内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。
因此人们提出另外一种“标记-整理”(Mark-Compact)算法由于老年代中的对象生存周期都叫长,有人提出“标记-整理”算法,标记过程和“标记-清理”一样,但在清除已死对象的同时会对存活对象进行整理,这样可以减少碎片空间。
图:标记-整理算法示意图
4.分代收集
当前商业虚拟机的垃圾收集都是采用“分代收集”(Generational Collecting)算法,这种算法并没有什么新的思想出现,只是根据对象不同的存活周期将内存划分为几块。一般是把Java堆分作新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就用复制算法,只要少量复制成本就可以完成收集。而老年代中因为对象的存活率较高、周期长,就用“标记-整理”或“标记-清除”算法来回收。
分享到:
相关推荐
本文将详细探讨JVM的发展历程以及内存管理中的垃圾回收机制。 一、JVM的历史发展 1. **早期阶段**:1995年,Sun Microsystems发布了Java的第一个版本,JVM作为其核心组成部分,主要应用于嵌入式设备和网络应用。初...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
JVM的学习可以从其基本结构、代码编译和执行过程,以及内存管理和垃圾回收机制三个方面进行深入探讨。 首先,JVM的基本结构分为逻辑结构和物理结构。逻辑结构主要包括Java源码编译器、JVM执行引擎、类加载器等组件...
垃圾回收的工作流程包括三个主要阶段:标记、筛选和回收。标记阶段确定哪些对象是活动的;筛选阶段决定哪些对象应被移除;回收阶段则是实际释放内存的过程。为了提高效率,JVM通常会区分新生代和老年代,对不同代的...
**JVM学习笔记(Java虚拟机)** Java虚拟机(JVM)是Java语言的核心组成部分,它是Java程序运行的平台,负责解释和执行字节码。深入理解JVM对于优化Java应用程序性能至关重要。本笔记将从以下几个方面详细介绍JVM:...
这份资料出自B站上的【狂神说Java】系列教程,为快速入门JVM提供了详实的笔记。以下是根据这些资源可能包含的一些关键知识点的详细解析: 1. **JVM概述**: - JVM是Java平台的核心组成部分,它是一个运行Java字节...
Java8 Jdk JVM学习笔记、jdk1.8、SpringBoot; 主要内容为 JVM 内存与垃圾回收、类加载子系统、运行时数据区、本地方法等。适合开发1-3年想对JVM学习的同学。 在之后的开发中,更加详细的了解JVM,可以进行JVM问题...
Java虚拟机(JVM)是Java程序运行的基础,它是一个抽象的计算机系统,负责执行Java字节码。本文将深入探讨JVM的工作...这本《JVM工作原理学习笔记》应包含了这些内容的详细讲解,对于学习和提升JVM相关知识极具价值。
Java 虚拟机学习笔记: Java 内存区域, 垃圾收集, 内存分配与回收策略, JVM 调优, 文件结构, 类加载机制, Java 程序 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,...
在JVM的学习中,理解其内存模型、垃圾收集算法以及类加载机制至关重要。 1. **JVM内存模型** - **方法区**:也称为“永久代”,存储虚拟机加载的类信息、常量、静态变量等,是线程共享的区域。在Java 8之后,这...
自己总结的jvm中内存和垃圾回收的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合jvm的爱好者和学习者
本篇JVM学习笔记主要关注对象声明、相关内存分配方法以及虚拟内存的物理和虚拟寻址概念。 首先,我们来看对象声明。在Java中,对象是在堆上创建的。例如,`CHeapObj` 类展示了如何在C++中模拟Java对象在堆上的分配...
这份“JVM的学习笔记PDF版”应该包含了关于JVM的详细信息,帮助学习者深入理解这个复杂的系统。JVM允许Java代码跨平台运行,通过解释器、类加载器、垃圾收集器等组件实现“一次编写,到处运行”的理念。 1. **JVM...
Java垃圾回收(Garbage Collection, 简称GC)是Java编程语言中一项重要的自动内存管理机制,...通过阅读"Java学习笔记_垃圾回收.pdf",你将进一步深入理解这个主题,掌握如何在实际项目中有效利用和优化垃圾回收机制。
《JVM学习笔记》 Java虚拟机(JVM)是Java平台的核心组成部分,它负责运行所有的Java应用程序。这篇笔记将深入探讨JVM的工作原理、内存管理、类加载机制以及优化策略,帮助读者全面理解JVM并提升Java程序的性能。 ...
一:上篇——内存与垃圾回收器 二:中篇——字节码与类的加载 三:下篇——性能监控与调优篇 一: 上篇——内存与垃圾回收器 架构: jvm依赖的架构: 栈架构/寄存器架构 栈架构 JVM的生命周期: 1.启动 通过引导类加载...
本学习笔记旨在全面解析JVM的工作原理,涵盖内存管理、类加载机制、垃圾收集、性能调优等多个关键领域,帮助读者从基础到深入地掌握JVM。 1. **JVM结构与运行过程** - JVM由类装载器、运行时数据区、执行引擎、...
JVM的垃圾收集机制负责自动回收不再使用的对象所占用的内存,主要有标记-清除、复制、标记-整理和分代收集等算法。理解垃圾收集的工作原理,可以帮助我们设置合理的内存参数,避免Full GC的发生,提高应用的响应速度...