深入理解Java虚拟机之经典垃圾收集器

深入理解Java虚拟机之经典垃圾收集器

为什么需要垃圾收集器

Java虚拟机需要对内存中无用的对象进行清理,以便为新对象腾出空间,避免OutOfMemoryError异常。Java虚拟机中的垃圾收集器可以自动回收无用对象,减少程序员手动管理的工作量。

垃圾回收的基本过程

垃圾回收的基本过程分为两个步骤:标记和垃圾回收。

标记阶段:
- 遍历根对象,将根对象活跃的对象标记为存活。
- 遍历存活对象的所有引用,将其所包含的对象标记为存活。
- 重复上一步的过程,直到所有可到达的对象都标记为存活,这个过程被称为“可达性分析”。

垃圾回收阶段:
- 将重复利用的内存空间挑选出来,这部分内存空间将作为下一轮存储使用过的对象空间。
- 遍历整个堆空间,将未被标记的对象移回到空间池,将处理过的对象移动到下一轮可用的内存空间中。

常见的垃圾回收算法

标记-清除算法

标记-清除算法分为两个阶段:标记,清除。
- 标记阶段:所有的存活对象都被标记,未被标记的都是垃圾对象。
- 清除阶段:被判定为垃圾的对象将会被清除。

缺陷:
1. 标记阶段和清除阶段都需要暂停整个应用程序,会影响用户体验。
2. 清除后内存空间不连续而且散乱,会影响后续分配内存的效率。
3. 对象引用可以被多个对象引用,如果其中一个对象被回收,则其可能影响其他对象的使用,引发dangling pointer问题。

复制算法

复制算法将可用的内存空间与垃圾回收保持完全分离,垃圾对象被回收后,剩下的内存会被整理,从而避免内存碎片化的问题。

步骤:
1. 将总可用内存空间一分为二,每个内含一半的空间。
2. 选取一半的空间进行对象分配。
3. 遍历已分配的对象,将其复制到另一半空间中。
4. 清理已分配的半部分空间,使其可变为下一轮分配使用。

复制算法的不足:
1. 只有一半的内存作为可用空间,不满足如今内存容量需求。
2. 复制算法只有一半的内存作为可用空间,正常情况下每一个对象被复制的次数都比较少,如果要存放所有的对象,那么我们需要将这个内存空间分成N份,复制N-1次才能将对象复制到这N份内存当中,复制的次数会明显增多。

标记-整理算法

去除标记-清除算法的缺陷,可以用标记-整理算法。标记-整理算法在标记阶段让不活跃的对象变成垃圾,清除阶段将所有存活的对象压缩到连续的内存空间中,并把未压缩的内存清理干净。

步骤:
1. 标记存活对象。
2. 将存活对象移到连续的内存地址中,而不是清除所有未被标记的存活对象。
3. 重置所有指针,以正确指向移动后的位置。
4. 清理不需要的内存区域。

示例说明

示例1:标记-清除算法的不足

在代码中定义了一个对象o1,并将其引用赋值给了o2

Object o1 = new Object();
Object o2 = o1;

在执行过程中,o1o2两个引用在栈内存上均指向堆内存中的同一对象。

若在外部执行了如下操作:

o1 = null;

此时,堆内存中的对象被标记为不再被引用,即为垃圾对象,但由于o2仍持有该对象的引用,此对象并不会被标记-清除算法回收,这就导致了内存泄漏。

示例2:复制算法的缺陷

在以下一个数组中进行对象分配:

Object[] arr = new Object[1000000];

当使用复制算法将数组分割为两个可用的内存空间进行对象分配时,如果数组的大小比分割后的空间还要大,就无法进行对象分配。此时需要使用滚动式压缩算法,在回收时将存活对象从内存里面移动到一端,并在移动后更新所有的被指向该对象的指针,从而减少内存压力。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Java虚拟机之经典垃圾收集器 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java 汇编JVM编写jasmin程序的操作方法

    Java汇编是一种利用Jasmin工具编写JVM汇编代码的技术。在Java虚拟机中,Jasmin程序就相当于Java程序源代码,可以通过JVM将其转化为可执行的二进制代码。以下是Java汇编JVM编写jasmin程序的完整实现攻略。 步骤一:安装Jasmin Jasmin是一个免费的开源工具,可以从其官方网站下载最新版本:http://jasmin.sour…

    Java 2023年5月23日
    00
  • 养成良好java代码编码规范

    为了帮助大家养成良好的Java代码编码规范,我们可以采用以下步骤: 1. 确认编码规范 首先,我们需要确认所使用的编码规范。Java有多种编码规范,如Oracle官方的编码规范,Google的编码规范等。我们需要根据自己的工作需要选择一种合适的编码规范,并在工作中严格遵守。 2. 遵循命名规范 在编写Java代码时,变量、函数、类等的命名应该符合命名规范,具…

    Java 2023年5月20日
    00
  • 浅谈Maven的安装及修改为阿里云下载依赖

    下面是详细的“浅谈Maven的安装及修改为阿里云下载依赖”的完整攻略。 一、Maven的安装 下载Maven:打开官方网站 https://maven.apache.org/download.cgi 找到最新的 Maven 安装包,选择apache-maven-x.x.x-bin.zip下载。 安装Maven:将下载的 Maven 安装包解压到指定目录下(如…

    Java 2023年5月20日
    00
  • spring security与corsFilter冲突的解决方案

    对于Spring Security和CORS(跨来源资源共享)Filter的异军突起,可能是由于两者在处理跨域请求的方式不同而导致的。Spring Security需要进行身份验证和授权,而CORS Filter是一个基于Web的安全工具,它帮助Web应用程序实现跨域请求。这两者之间的冲突可能会导致无法登录或提供受限制的访问。 下面是解决此问题的步骤: 1.…

    Java 2023年5月20日
    00
  • SpringBoot注入自定义的配置文件的方法详解

    当我们开发一个SpringBoot应用时,我们通常需要使用一些配置文件来配置我们的应用程序,例如application.properties或application.yml文件。但是,有时我们需要注入我们自己的配置文件,例如redis.properties或mysql.properties等。那么,本文将介绍如何将自定义配置文件注入到SpringBoot应用…

    Java 2023年5月26日
    00
  • Java的Struts框架报错“ViewHandlerException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“ViewHandlerException”错误。这个错误通常由以下原因之一起: 视图处理器配置错误:如果配置文件中没有正确配置视图处理器,则可能会出现此错误。在这种情况下,需要检查文件以解决此问题。 视图文件不存在:如果视图文件不存在,则可能会出现此错误。在这种情况下,需要检查文件路径以解决此问题。 以下是两个…

    Java 2023年5月5日
    00
  • Farpoint的简单用法简要概述

    Farpoint的简单用法简要概述 Farpoint是一款由美国开发商研发的企业级Excel组件,旨在增强Excel的导入导出、处理、编辑等功能,提高研发、业务等效率。Farpoint可以集成在.NET版本的Visual Studio中,使用也较为简单。本篇攻略将详细讲解Farpoint的简单用法,帮助开发者更好地使用该组件。 1. Farpoint的安装与…

    Java 2023年6月16日
    00
  • SpringBoot统一处理功能实现的全过程

    SpringBoot是一种轻量级的Java框架,提供了一种快速开发的方式,这是因为它提供了大量的自动化配置。SpringBoot为Java开发人员提供了快速开发微服务应用程序所需的各种组件。其中包含了很多与Web应用程序相关的组件,包括MVC(Model-View-Controller)框架。本文将讲解如何实现一个SpringBoot应用程序的统一处理功能,…

    Java 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部