Java垃圾回收机制深入理解

2023-11-03

一、简介

Java垃圾回收机制是Java虚拟机(JVM)的核心组件之一,对于内存管理起到至关重要的作用。它能自动追踪并管理应用程序中创建的对象,当这些对象不再使用时,垃圾回收机制会自动回收其占用的内存,使这部分内存能够被再次利用。此机制极大地减少了开发者需要手动管理内存的负担,防止了因为疏忽导致的内存泄漏问题,是Java语言相较于C++等其他语言的一个显著优点。

二、Java内存结构

Java内存主要被划分为五个区域:

  1. 方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量等数据。
  2. 堆(Heap):Java Heap是JVM所管理的最大一块内存区域,几乎所有的对象实例以及数组都要在堆上分配。它还被划分为新生代和老年代两个部分,用于进行高效的内存分配和回收。
  3. 虚拟机栈(Java Stack):每个线程有一个私有的栈,其生命周期与线程同步。栈帧存储了局部变量表、操作数栈、动态链接和方法出口等信息。
  4. 本地方法栈(Native Method Stack):本地方法栈与虚拟机栈类似,只不过它是为本地(Native)方法服务的。
  5. 程序计数器(Program Counter Register):它是当前线程所执行的字节码的行号指示器。

其中,方法区和堆是Java垃圾收集器关注的主要区域,也是我们接下来讨论的重点。

三、什么是垃圾

在Java中,对象的生命周期从创建(new)开始,到不再被其他对象引用结束。换句话说,当一个对象没有任何引用指向它时,这个对象就成了垃圾,等待垃圾回收器的回收。值得注意的是,对象可能还在作用域中,但已经不可能被程序再次使用(如:对象只在一个局部作用域中使用),此时这个对象也会被视为垃圾。垃圾回收器的主要工作就是找出这些垃圾对象并释放它们占用的内存,从而为新的对象提供空间。

四、垃圾收集算法

1. 标记-清除算法(Mark and Sweep)

这是最基础的垃圾收集算法。它分为两个阶段:标记阶段和清除阶段。标记阶段会遍历所有的对象,找出还活着的对象。清除阶段则会清除掉所有未被标记的对象。如图:
在这里插入图片描述

虽然标记-清除算法很直观,但存在两个问题:一是效率问题,标记和清除两个过程的效率都不高;二是空间问题,标记清除之后会产生大量不连续的内存碎片。

2. 复制算法(Copying)

为了解决效率问题,可以采用"复制"算法。复制算法将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当这一块内存用完了,就将还活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次性清理掉。这样使得每次都是对其中一块进行内存回收,内存分配时也就不用考虑内存碎片等问题。如图:

在这里插入图片描述
复制算法虽然实现简单,内存效率高,不易产生碎片,但是最大的问题是可用内存被压缩到了原本的一半,未充分利用内存。且存活对象增多的话,复制算法的效率会大大降低。

3. 标记-整理算法(Mark and Compact)

为了解决空间问题,可以使用"标记-整理"算法。标记过程仍然与"标记-清除"算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。如图:
在这里插入图片描述

4. 分代收集算法(Generational Collection)

当前商业虚拟机的垃圾收集都采用"分代收集"(Generational Collection)算法。这种算法把Java堆分为新生代和老年代,这样我们就可以根据各个年代的特点采用最适当的收集算法。在对象存活率低的新生代,可以选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,我们可以选择"标记-清理"或者"标记-整理"算法进行垃圾收集。

注意,Java本身并不提供直接控制这些垃圾收集算法的API,它们是由Java虚拟机在后台自动执行的。然而,理解这些基础的垃圾收集算法是理解更高级的垃圾收集技术(如:并行收集、并发收集、增量收集等)的基础。

五、垃圾收集器

Java HotSpot VM包含几种类型的垃圾收集器,每一种都有各自的特点,适用于不同的系统和使用场景。包括:

  • Serial收集器:单线程收集器,它在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。
  • Parallel收集器:多线程收集器,它在垃圾收集时,会停止其他所有的工作线程,直到它收集结束。
  • CMS (Concurrent Mark Sweep)收集器:并发收集器,它主要的设计目标是避免在老年代垃圾收集时出现长时间的卡顿。
  • G1 (Garbage First)收集器:它是一款面向服务端应用的垃圾收集器,它能满足垃圾收集停顿时间可预测以及高吞吐量的需求。

需要注意的是,每种垃圾收集器都有其适用的场景,没有绝对的好坏之分。在实际的系统设计和开发中,我们需要根据应用的特性(如:是否对系统响应时间有较高要求等)和硬件资源来选择最合适的收集器。

六、垃圾回收的触发时机

在Java中,垃圾回收的触发时机是由JVM来决定的。虽然我们可以通过调用System.gc()方法来请求JVM进行垃圾回收,但这只是一个建议,JVM可以选择忽略这个请求。

在实际情况中,JVM通常会在以下几种情况下进行垃圾回收:

  • 当JVM的堆内存空间不足时,JVM会触发垃圾回收,以释放不再使用的对象占用的内存,从而为新的对象分配空间。
  • 当一个Old Generation(老年代)空间满时,会触发一次Full GC,这会导致所有的Java应用线程暂停,直到GC结束。
  • 当系统空闲时,JVM也可能会选择执行垃圾回收,以提高系统的内存使用效率。

下面的Java代码将显示在运行过程中垃圾回收的执行情况:

public class GCDemo {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        long before = runtime.freeMemory(); //获取开始时JVM空闲内存
        for (int i = 0; i < 1000000; i++) {
            String s = new String("Hello, World!");
            s = null; // 显式地断开s的引用,使得s所指向的对象可以被垃圾回收
        }
        long after = runtime.freeMemory(); //获取结束时JVM空闲内存
        System.out.println("Memory freed by GC: " + (before - after));
    }
}

这段代码会输出由垃圾回收器释放的内存量,可以看到,即使我们没有显式地触发垃圾回收,JVM也会在适当的时机进行垃圾回收。

结语

理解和掌握Java的垃圾回收机制对于编写高效、稳定的Java程序至关重要。在这篇博客中,我们介绍了垃圾回收机制的基本原理,JVM的内存结构,垃圾回收算法,各种垃圾收集器,以及垃圾回收的触发时机。虽然Java已经为我们处理了大部分的内存管理问题,但是,作为Java开发人员,我们仍然需要理解这些基本的概念,才能写出更有效率的代码,并避免出现内存泄漏等问题。希望这篇博客对你有所帮助,如果你有任何问题,欢迎留言讨论。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java垃圾回收机制深入理解 的相关文章

随机推荐

  • 2022-2023 通信工程专业毕业设计题目选题推荐 - 100例

    文章目录 1前言 2 如何选题 3 通信工程选题方向 2 1 移动通信方向 2 2 嵌入式开发方向 2 3 人工智能方向 2 4 物联网方向 2 5 算法研究方向 2 6 移动应用开发方向 2 7 网络通信方向 3 4 学长作品展示 4 最
  • 二维码PDF417简介及其解码实现(zxing-cpp)

    二维码PDF417是一种堆叠式二维条码 PDF417条码是由美国SYMBOL公司发明的 PDF Portable Data File 意思是 便携数据文件 组成条码的每一个条码字符由4个条和4个空共17个模块构成 故称为PDF417条码 P
  • 【C#学习笔记】数组使用

    using System namespace ConsoleApplication class Program static void Main string args int a new int 3 一维数组 int a new int
  • 如何通过cpolar内网穿透+VNC实现公网远程ubuntu

    文章目录 前言 1 ubuntu安装VNC 2 设置vnc开机启动 3 windows 安装VNC viewer连接工具 4 内网穿透 4 1 安装cpolar 支持使用一键脚本命令安装 4 2 创建隧道映射 4 3 测试公网远程访问 5
  • 毕业设计-基于协同过滤算法的电商平台推荐系统

    目录 前言 课题背景和意义 实现技术思路 一 文献综述 二 基于用户协同过滤推荐系统算法 三 实证分析 四 总结 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计
  • mysql DATE_FORMAT导致索引失效

    最近在优化一个统计的接口 在几十万的数据统计下 接口处理的响应时间达到了20s 看了下代码逻辑 发现其中主要有三个主要的统计方法 在优化了其中一个方法的统计逻辑后 接口的响应时间下降到了3s内 还是没有达到期望的响应时间 1s内 看了下另外
  • 决策树——依据水果特征分类

    文章目录 一 获取数据集 1 提取数据 2 划分数据 二 计算信息增益 1 信息熵 2 计算信息增益 三 绘制决策树 四 分类预测 一 获取数据集 水果中苹果和杨桃外部特征比较鲜明 例如下面两张苹果 杨桃图片 苹果颜色为红色 形状大致为椭圆
  • 优化代码逻辑之 K-近邻算法之鸢尾花实例 使用Spark实现KNN的Demo2

    这篇代码是KNN的优化 代码就是 flatMap里面的结构转换 和aggregate的应用感觉有点难理解 但是思想简单 首先要知道这个优化是基于 有个大数据的思想 分而治之 求出一份数据最大的前一百个数 如果数据太多 内存太小 则将数据切割
  • AndroidStudio AIDL 示例代码详细步骤

    AIDL Android Interface Definition Language 即Android接口定义语言 最近在看Binder的原理 Android里面AIDL就是Binder的经典实现 先记录一下AIDL的使用步骤 1 服务端S
  • 神奇的master公式(递归行为时间复杂度)

    master master公式是干嘛的呀 master公式是干嘛的呀 master是一个对于递归行为时间复杂度的估算 公式为 T N a T N b O N d 不用急我们来举一个栗子 我们先来看看二分法求最大值的代码 public int
  • 疯狂的程序员--绝影

    该博客转自新浪博客 作者 疯狂之桥 网址 http blog sina cn dpool blog s blog a46817ff010157cf html vt 4 今天看到绝影的CSDN博客由于种种原因被关闭了 心中有种说不出的感觉 感
  • python爬虫(一)

    目录 前言 一 爬虫简介 1 1 Python爬虫 1 2 robots协议 二 爬虫分类 2 1 通用网络爬虫 2 2 垂直网络爬虫 2 3 增量式网络爬虫 2 4 分布式网络爬虫 2 5 深度网络爬虫 2 6 搜索引擎爬虫 三 爬虫构造
  • [学习交流] OC学习笔记之id类型及应用场景

    1 NSObject访问子类方法 NSObject是所有类的基类 可以指向任何子类 例如 import
  • 【暴力破解】dvwa

    dvwa暴力破解练习 1 low 首先进行抓包 将包发送到intruder 然后对用户及密码进行暴力破解 成功 Mid 在low的基础上添加了一定的时延 不适合大量字典 但是爆破方式与low相同 High 点击进表单页面抓包包1 放掉之后再
  • parseInt()详解

    可能绝大多数学过js的就知道parseInt 函数 这里对小伙伴来说是有一个难点或者说是误区的 好吧 说的就是我 那就是在官方给的解释中我们能看到其中一个参数 radix 文中多次说他为基数 千万不要把它理解为要转换的进制 看上面的这些可能
  • docker 重启gitlab_Gitlab+CICD自动化部署Python项目

    使用CICD原理 当我们push项目到gitlab 就会触发 gitlab ci yml 文件 文件里面的 only maste表示 当push的分支为master则执行脚本 执行时通过tags shell选择已有的runner去执行 这时
  • 微信小程序——关于时间

    获取当前时间 var time new Date var year dateNow getFullYear var month dateNow getMonth 1 var day dateNow getDate var date year
  • 【2023最新版】Linux (WSL:Ubuntu22.04)安装Go1.20.6+Win11:安装Go1.20.6+GoLand2023.1.4+配置环境

    目录 一 Windows安装Go 1 下载地址 2 安装 3 配置Go环境变量 位置 默认添加的环境变量 修改环境变量 新建以下文件夹 检查 二 Linux WSL 安装Go 1 下载 2 解压缩 3 查看安装在系统上的Go版本 4 设置G
  • 《操作系统》- 操作系统的基本概念

    目录 一 操作系统的概念 1 1 操作系统的分类 1 2 计算机系统的构成 1 3 操作系统都做了哪些事 二 操作系统的目标和功能 2 1 操作系统的目标 2 2 操作系统的功能 三 操作系统的特征 3 1 并发 3 2 共享 3 3 虚拟
  • Java垃圾回收机制深入理解

    文章目录 一 简介 二 Java内存结构 三 什么是垃圾 四 垃圾收集算法 1 标记 清除算法 Mark and Sweep 2 复制算法 Copying 3 标记 整理算法 Mark and Compact 4 分代收集算法 Genera