当前位置: 首页 > news >正文

JVM 双亲委派模型以及垃圾回收机制

目录

1. JVM 内存区域划分

2. JVM 中类加载的过程

1) 类加载的基本流程

2) 双亲委派模型

3. JVM 中垃圾回收机制

1) 找到垃圾

a) 引用计数

b) 可达性分析

2) 释放垃圾


1. JVM 内存区域划分

一个运行起来的 Java 进程,其实就是一个 JVM 虚拟机。

而进程是资源分配的基本单位,所以 JVM 就首先会申请一大块内存,然后把这个内存划分成不同的区域,每个区域都有不同的作用。

JVM 内存区域划分成以下四个部分:

1. 方法区 (1.7 及之前) / 元数据区 (1.8 开始)

方法区存储的内容,就是类对象。( .class 文件加载到内存之后,就成了类对象)

2. 堆

这里存储的内容,就是代码中 new 的对象。

堆是占据空间最大的区域。

3. 虚拟机栈(就是平常我们所说的栈)

这里存储的内容,就是代码执行过程中,方法之间的调用关系。

4. 程序计数器

是个比较小的空间,主要用来存放一个 "地址",这个地址,就表示了下一条要执行的指令,在内存中的哪个地方(方法区里)。

每个方法,里面的指令,都是以二进制的形式, 保存到类对象中的。

 刚开始调用方法的时候,程序计数器记录的就是方法的入口的地址。

随着一条一条的执行指令,每执行一条指令,程序计数器的值都会自动更新,去指向下一条指令。

程序计数器和虚拟机栈是每个线程都有一份,而堆和方法区在 JVM 进程中是只有一份的。

在 Java 里,每个线程都有自己私有的栈空间。

2. JVM 中类加载的过程

1) 类加载的基本流程

java 代码会被编译成 .class 文件(包含了一些字节码),java 程序想要运行起来,就需要让 JVM 读取到这些 .class 文件,并把里面的内容,构造成类对象,保存到内存的方法区中。 

官方文档把类加载的过程主要分成了 5 个步骤。

1. 加载:找到 .class 文件,打开文件,读取文件内容。

往往代码中,会给定某个类的 "全限定类名"(比如 java.lang.String,java.util.ArrayList) ,JVM 就会根据这个类名,在一些指定的目录范围内查找。

2. 验证: .class 文件是一个二进制的格式。(某个字节,都是有某些特定含义的),就需要验证你当前读到的这个格式是否符合要求。

3. 准备:给类对象分配内存空间(最终的目标,是要构造出类对象)

这里只是分配空间,还没有初始化,此时这个空间上的内存的数值,就是全 0 的,此时如果尝试打印类的 static 成员,就是全 0 的。

4. 解析:针对类对象中包含的字符串常量进行处理,进行一些初始化操作。

java 代码中用到的字符串常量,在编译之后,也会进入到 .class 文件中。

5. 初始化:针对类对象进行初始化。

把类对象中需要的各个属性都设置好。

还需要初始化号 static 成员

还需要执行静态代码块

以及可能还需要加载一下父类。

总结类加载的基本流程:

1. 加载:找到 .class 文件,打开 .class 文件,读取 .class 文件

2. 验证:验证当前 .class 文件格式是否正确

3. 准备:给类对象分配内存空间

4. 解析:将符号引用替换成直接引用

5. 初始化:初始化类对象

2) 双亲委派模型

属于类加载中第一个步骤 "加载" 中的一个环节,是负责根据全限定类名,来找到 .class 文件的。

类加载器,是 JVM 中的一个模块(专门负责类加载的操作)。

JVM 中,内置了三个类加载器:

1. BootStrap ClassLoader           爷

2. Extension ClassLoader           父

3. Application ClassLoader         子

这个父子关系,不是继承构成的,而是这几个 ClassLoader 里有一个 parent 这样的属性,指向了一个 父 "类加载器"。

程序员也可以手动创建出新的类加载器。

所以说,双亲委派模型,就是一个查找优先级的问题,先找标准库,再找扩展库,最后找第三方库。

3. JVM 中垃圾回收机制

在 Java 中,new 一个对象,就是 "动态内存申请",在 C 语言中,使用 malloc 这种 "动态内存申请" 的函数,使用完之后,就需要手动调用 free 释放内存,如果不释放,就会出现内存泄露这样的问题,而在 Java 中就不用手动释放内存,因为 JVM 自动判定,是否某个对象已经不再使用了,并帮我们进行释放不再使用的对象的内存了。像这种不再使用的对象,就称之为 "垃圾",这种机制,也就叫做 GC 垃圾回收机制。

GC 也有缺陷:

1. 系统开销,需要有一个/一些特定的线程,不停的扫描你内存中的所有的对象,看是否能够回收,此时是需要额外的内存和 CPU 资源的。

2. 效率问题,这样的扫描线程,不一定能够及时的释放内存 (扫描总是有一定周期的),一旦同一时刻,出现大量的对象都需要被回收,GC 产生的负担就会很大,甚至引起整个程序都卡顿 (STW 问题    stop   the   world)

但是 GC 属于大势所趋,Python,PHP,Go.... 都是具有 GC 机制的。

GC 是垃圾回收,GC 回收的目标,其实是 内存中的 对象。

对于 Java 来说,就是 new 出来的这些对象。

栈里的局部变量,是跟随着栈帧的生命周期走的。(方法执行结束,栈帧销毁,内存自然释放)

静态变量,生命周期就是整个程序,这就意味着 静态变量 是无需释放的。

因此真正需要 gc 释放的对象就是 堆 上的对象。

gc 可以理解成两个大的步骤:

1. 找到垃圾

2. 释放垃圾

1) 找到垃圾

在 GC 的圈子中,有两种主流的方案:1. 引用计数     2. 可达性分析 (Java 采用的是这种)

a) 引用计数

new 出来的对象,单独安排一块空间,来保存一个计数器。

b) 可达性分析

可达性分析,本质上是一个时间换空间这样的手段。

有一个/一组线程,周期性的扫描代码中的所有对象。

从一些特定的对象出发,尽可能的进行访问的遍历,把所有能够访问到的对象,都标记成 "可达",反之,经过扫描之后,未被标记成 "可达" 的对象,就是垃圾了。

就跟二叉树的遍历差不多,只不过不是二叉树,而是 N 叉树。

2) 释放垃圾

有三种基本的思路:

1. 标记清除

是一种比较简单粗暴的方式。

2. 复制算法

第二种思路,就是解决,刚刚标记清除出现的内存碎片的办法。

通过复制的方式,把有效的对象,归类到一起,再统一释放剩下的空间。

3. 标记整理

既能够解决内存碎片的问题,又能够处理复制算法中利用率。

类似于顺序表删除元素的搬运操作。

实际上,JVM 采取的释放思路,是上述基础思路的结合体。

分代回收:

分代回收,对象能活过的 GC 扫描轮次越多,就是越老。

相关文章:

JVM 双亲委派模型以及垃圾回收机制

目录 1. JVM 内存区域划分 2. JVM 中类加载的过程 1) 类加载的基本流程 2) 双亲委派模型 3. JVM 中垃圾回收机制 1) 找到垃圾 a) 引用计数 b) 可达性分析 2) 释放垃圾 1. JVM 内存区域划分 一个运行起来的 Java 进程,其实就是一个 JVM 虚拟机。 而进程是…...

Delphi编写涂鸦桌面的小程序

用Delphi编写涂鸦桌面的小程序,类似于腾讯会议中的画板功能的实现。这里用Delphi实现代码给大家提供一些思路; 首先,新建一个Application,将Form1的WindowState设为wsMaximized,BorderStyle设为bsNone。这样做的目的就…...

智星云技术文档:GPU测速教程

安装gpu burn git clone https://github.com/wilicc/gpu-burn cd gpu-burn/ make测试 ./gpu_burn 60100.0% procd: 14280 (7373 Gflop/s) - 13390 (6997 Gflop/s) - 15912 (7110 Gflop/s) - 13184 (7055 Gflop/s) - 13464 (7369 Gflop/s) - 13974 (7351 Gflop/s) - 16626 (7…...

《Kali Linux 软件源更换攻略:优化软件获取与系统更新》

KALI为什么要换源 速度提升 Kali Linux 默认的软件源服务器通常位于国外。在从这些国外源下载软件包、更新系统时,会受到网络带宽、网络延迟等因素的限制。例如,在中国,连接到国外服务器的网络速度可能较慢,尤其是在下载大型软件…...

C# 在dataview可以直接增删改查mysql数据库

C# 在dataview可以直接增删改查mysql数据库 首先,确保你的项目中已经安装了MySql.Data。你可以通过NuGet包管理器安装它: Install-Package MySql.Data -Version 8.0.28using System; using System.Data; using MySql.Data.MySqlClient;public class My…...

C#—泛型约束

C#—泛型约束 概念: 泛型约束就是告知编译器类型参数必须具备的功能。 在没有任何约束的情况下,类型参数可以是任何类型。 编译器只能假定 System.Object 的成员,它是任何 .NET 类型的最终基类。当分配给泛型的类型参数不满足约束的类型时&…...

MeiliSearch:一款轻量级开源搜索引擎

Meilisearch 是由 Meili (一家总部位于法国的软件开发公司)创建的搜索引擎,目前在 Github 上有 47.9k stars。 Meillisearch 具备以下特色功能(ChatGPT-4o 翻译): 混合搜索:结合语义搜索和全文…...

Ansible playbook 详解与实战操作

一、概述 playbook 与 ad-hoc 相比,是一种完全不同的运用 ansible 的方式,类似与 saltstack 的 state 状态文件。ad-hoc 无法持久使用,playbook 可以持久使用。 playbook 是由一个或多个 play 组成的列表,play 的主要功能在于将事先归并为一…...

青少年夏令营管理系统的设计与开发(社团管理)(springboot+vue)+文档

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

加速合并,音频与字幕的探讨

因上一节。合并时速度太慢了。显卡没用上。所以想快一点。1分钟的视频用了5分钟。 在合并视频时,进度条中的 now=None 通常表示当前处理的时间点没有被正确记录或显示。这可能是由于 moviepy 的内部实现细节或配置问题。为了加快视频合并速度并利用 GPU 加速,可以采取以下措…...

Uniapp插件如何通过NFC读取多种证卡信息?

nfc读卡uniapp插件,由中软高科进行开发,主要是通过NFC读取居民身份证、港澳台居住证、外国人居住证、护照等证卡的信息。经过多个版本的升级更新,目前性能已趋于稳定,并且读卡速度较之最初版本有了大的提升。 注意事项 测试使用的…...

米哈游C++开发精选60道面试题及参考答案

C++ 面向对象的三个特征 封装是把数据和操作数据的函数捆绑在一起,并且对数据的访问进行限制。这样做的好处是可以隐藏对象的内部实现细节,只暴露必要的接口给外部。例如,在一个银行账户类中,账户余额这个数据成员是被封装起来的,外部不能直接访问和修改,而是通过存款、取…...

深度与视差的关系及其转换

深度与视差的关系及其转换 在计算机视觉和立体视觉中,深度和视差是两个重要的概念。理解这两者之间的关系对于实现立体图像处理、三维重建以及深度估计至关重要。在这篇博客中,我们将深入探讨深度和视差的概念,并介绍它们之间的转换关系。 …...

安全见闻全解析

跟随 泷羽sec团队学习 声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及…...

搭建Tomcat(四)---Servlet容器

目录 引入 Servlet容器 一、优化MyTomcat ①先将MyTomcat的main函数搬过来: ②将getClass()函数搬过来 ③创建容器 ④连接ServletConfigMapping和MyTomcat 连接: ⑤完整的ServletConfigMapping和MyTomcat方法: a.ServletConfigMappin…...

PT2044A 单触控单输出IC

1 产品概述 ● PT2044A 是一款单通道触摸检测芯片。该芯片内建稳压电路,提供稳定电压给触摸感应电路使用。同时内部集成高效完善的触摸检测算法,使得芯片具有稳定的触摸检测效果。该芯片专为取代传统按键而设计,具有宽工作电压与低功耗的特性…...

docker安装mysql5.7

1、宿主机创建映射目录 mkdir -p /data/mysql/log mkdir -p /data/mysql/data mkdir -p /data/mysql/conf这里我放在了/data/mysql目录下 2、拉取mysql镜像 docker pull mysql:5.7注意是5.7版本,如果是8版本操作会略有不同,下篇文章介绍安装8版本的操…...

安卓 文件管理相关功能记录

文件管理细分为图片、视频、音乐、文件四类 目录 权限 静态声明权限 动态检查和声明权限方法 如何开始上述动态申请的流程 提示 图片 获取图片文件的对象列表 展示 删除 视频 获取视频文件的对象列表 获取视频file列表 按日期装载视频文件列表 展示 播放 删除…...

GB28181系列三:GB28181流媒体服务器ZLMediaKit

我的音视频/流媒体开源项目(github) GB28181系列目录 目录 一、ZLMediaKit介绍 二、 ZLMediaKit安装、运行(Ubuntu) 1、安装 2、运行 3、配置 三、ZLMediaKit使用 一、ZLMediaKit介绍 ZLMediaKit是一个基于C11的高性能运营级流媒体服务框架,项目地址&#xf…...

ScottPlot学习的常用笔记

ScottPlot学习的常用笔记 写在前面版本的选择第一个障碍:版本问题。 ScottPlot4.0的官方网站与示例官方起始页cookbook5.0Demo4.1 demo以4.1为例,解压和运行如下: 下载源代码和编译先说结论: 写在前面 之前调研的TraceCompass&am…...

二、mapbox-gl实现白膜立体建筑

有时候我们只有二维的面数据,怎么实现类似高德地图中的白膜立体建筑呢?在mapbox-gl中很容易实现,具体如下。 要在Vue中结合Mapbox显示自定义的GeoJSON数据,并实现建筑物的白膜效果,我们需要执行以下步骤: …...

mybatisplus 分库查询

mybatisplus 分库查询 比如我们的项目有两个数据库 不同的表在不同的库 我们是可以使用mybatisplus来实现 首选引入pom <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><vers…...

计算属性 (vue3)

二 实例 1route.query.type...

RabbitMQ 安装、配置和使用介绍 使用前端js直接调用方式

1. 安装 RabbitMQ 1.1 安装 Erlang RabbitMQ 是基于 Erlang 语言开发的&#xff0c;因此首先需要安装 Erlang。 在 Ubuntu 上安装 Erlang&#xff1a; bash sudo apt-get update sudo apt-get install erlang 在 CentOS 上安装 Erlang&#xff1a; bash sudo yum insta…...

电脑显示器选购指南2024

选择显示器是五花八门的显示参数&#xff0c;如何选择&#xff0c;以下给出参数说明&#xff0c;及部分参考&#xff1a; 1. 尺寸和分辨率 尺寸&#xff08;英寸&#xff09; 根据使用距离和用途选择合适的屏幕尺寸&#xff1a; 21-24 英寸&#xff1a;适合小桌面空间、日常…...

vue2中如何实现自定义指令

实现自动聚焦功能 1.不用自定义指令 使用生命周期钩子mounted 2.使用自定义指令 1. 使用全局组件 首先在main.js中注册 然后在组件中直接使用v-指令名 2. 使用局部注册 局部注册和全局注册类似 如果很多组件需要自定义&#xff0c;建议使用自定义指令注册在全局...

QT从入门到精通(一)——Qlabel介绍与使用

1. QT介绍——代码测试 Qt 是一个跨平台的应用程序开发框架&#xff0c;广泛用于开发图形用户界面&#xff08;GUI&#xff09;应用程序&#xff0c;也支持非图形应用程序的开发。Qt 提供了一套工具和库&#xff0c;使得开发者能够高效地构建高性能、可移植的应用程序。以下是…...

【jpa】springboot使用jpa示例

目录 1. 请求示例2. pom依赖3. application.yaml4.controller5. service6. repository7. 实体8. 启动类 1. 请求示例 curl --location --request POST http://127.0.0.1:8080/user \ --header User-Agent: Apifox/1.0.0 (https://apifox.com) \ --header Content-Type: applic…...

Python Flask Web框架快速入门

Flask 入门Demo Flask 开发环境搭建&#xff0c;执行如下指令&#xff1a; pip install flask# 第一节: Flask 快速入门from flask import Flask app Flask(__name__)app.route(/flask) def hello_flask():return Hello Flaskapp.run()核心代码剖析&#xff1a; 从flask包导…...

ansible自动化运维(五)roles角色管理

目录 Roles角色管理 创建nginx的角色目录 定义任务配置文件&#xff1a; 定义jinjia2模板&#xff1a; 定义nginx yml文件 检查语法&#xff0c;执行命令 检验结果&#xff1a; Roles角色管理 角色&#xff08;roles&#xff09;是ansible自1.2版本开始引入的新特性&…...