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

八股文之JVM

目录

1.JVM内存划分

2.JVM类加载过程

3.JVM垃圾回收机制GC

3.1.判断谁是垃圾

3.2.如何释放对应的内存


1.JVM内存划分

在一个Java程序运行起来之后,jvm就会从操作系统中申请一块内存,然后就会将该内存划分成多个部分,用于不同的用途。

(1)主要划分成五个部分

堆、栈、元数据区(方法区)、常数计数器(很少涉及)

图示:

像堆区中的各个部分划分,在后面的垃圾回收机制再拿出来鞭策一遍,在这里就不先做任何的赘述。

(2)每块内存区的功能

堆区:

整个内存区域中最大的区域,用于存放java代码中new出来的对象、和成员变量。

栈:

一般java是使用jvm虚拟机栈,这里保存了方法的调用关系、局部变量等。也就是每个方法怎么被调用,被谁调用等

元数据区:

元数据区,以前也成为方法区,用来存放类对象、类属性(静态成员)、常量

程序计数器:

属于内存中最小的区域,用来保存要执行的下一条指令的地址

(3)实战划分内存

看下嘛的一段代码,查看下面的变量和对象分别处于哪一块内存中

class Demo2 {}
class Demo1 {public int a;Demo2 b = new Demo2();public String c = "love";public static int d;}public class Test {public static void main(String[] args) {Demo1 e = new Demo1();}
}

对于变量:a,b,c,d,e 其中a,b,c都属于成员变量,存在于堆上;而e属于局部遍历,存在栈上;而d属于静态成员变量,属于类属性,存在于元数据区。它们只是属于变量,里面存有一个值,会指向另一块内存空间。

各对象内存分布和指向关系

以上就是对应的各种关系。

对于上述的四个区域,堆和元数据区,在整个进程中只有一份,而栈和程序计数器,是每个线程都有一份。

2.JVM类加载过程

一个.java文件变成.class文件的过程,也是从硬盘加载到内存中,得到类对象的过程。

(1)类加载的五个环节

加载、验证、准备、解析、初始化

(2)每个环节对应的作用

1.加载

在硬盘上找到对应的.class文件,并且读取.class文件内容

2.验证

检查.class文件中的内容,是否符合要求(如文件格式等)

3.准备

给类对象分配内存空间

4.解析

对字符串常量初始化,把刚才.class文件中的常量内容取出来放到元数据区

5.初始化

针对类对象进行初始化,给静态成员初始化,也就是执行静态代码块

(3)“双亲委派模型”

在第一步的加载环节,目的是打开.class文件,前提就是需要通过“全限定类名”找到文件才能进行打开,所以“双亲委派模型”就是寻找.class文件的一种机制。

在这个环节,涉及到一个概念:类加载器

在JVM中也会包含一些类,负责完成后续的类加载工作。其中JVM内置了三个类加载器,负责加载不同的类

分别是三个类:BootstrapClassLoader、ExtentionClassLoader、ApplicationClassLoader

1)三个类加载器作用

所以成为双亲委派模型,但是跟准确的说法为:父亲委派模型或者单亲委派模型

2)加载过程

那么双亲委派模型是如何找类的呢?我们举一个例子,假设我们自己写了一个java程序,会给定一个全限定类名

3)双亲委派模型应对的场景

如果自己的代码中写的类的名字和标准库/扩展库冲突了,JVM会确保加载的类是标准库的类(不会加载自己写的类),如果标准库中的类无法加载,那么Java进行就没有办法正常工作了。

这样还有一个好处,就是可以确保自己写的类肯定可以被加载到。

3.JVM垃圾回收机制GC

对于Java,回收垃圾采取的是自动回收策略,策略也称为GC。

对于GC来说,回收的其实是堆上的内存。而对于堆,保存的主要是对象,换句话说,也就是主要回收对象,那怎么回收对象呢?主要有两个步骤:判断谁是垃圾和如何释放其对应的内存。

3.1.判断谁是垃圾

在判断谁是垃圾这一步,Java是采取很保守的做法,也就是可以保证只会释放后续不会再使用的对象,后续仍会使用到的对象,是不会进行回收的,所以才用的策略是:判断某个对象是否存在引用指向,如果没有引用指向,就可以判断为垃圾,反之不行。

判断谁是垃圾,GC有两种策略:引用技术和可达性分析,而JVM采取的策略只有可达性分析,引用计数则不是。

(1)引用计数

1)策略:每创建一个对象,就在对象前面多开辟一块空间,用来计数使用,有一个引用指向该对象,计数变量就+1,如果计数器为0,则需要回收该对象。

2)代码举例

class TT {}
public class GC {public static void main(String[] args) {TT a = new TT();TT b = a;}
}

对于实例化的TT对象,当前有两个对象指向它,所以计数值为2(分别是引用a和b),如果a=null或者b=null,则计数值-1,两个都置为null,则计数为0.

对于引用计数存在两个问题

问题一:会消耗额外的内存空间

如果对象本身的内存比较大,相比来说计数的空间就很小;但是如果对象内存空间很小,那么计数空间就会显得很大,就会浪费很大的空间

问题二:存在“循环引用”问题

这类问题就会让外部代码无法对 对象进行释放

代码举例:

class T {T t;
}
public class GC {public static void main(String[] args) {T a = new T();T b = new T();a.t = b;b.t = a;}
}

这是一段有问题的代码

图示分析:

存在的问题:当将引用a和b置为null时,按理来说这两个对象是要被回收了,但是这里却不会,因为计数不为0,不能回收。所以这就是引用计数最大的一个问题。

(2)可达性分析

JVM采取的是可达性分析,既解决了空间问题,也解决了循环引用问题。

1)定义:JVM会把对象之间的引用关系,定义成树形结构,JVM可以不停的从根节点开始遍历,可以访问到的对象,成为“可达”,剩下的就是“不可达”。

标记为不可达的对象,也就被标记成垃圾。

2)举例

例如这样的结构,如果将c=null,那么c后面的两个对象f和g就变成不可达,就要成为垃圾。

访问这棵树的所有节点,都是要通过根节点a开始。

3)确定根节点

对于根节点,可能的情况有:栈上的引用局部变量、常量池中引用的对象、方法区中的静态成员。

3.2.如何释放对应的内存

当已经标记好垃圾之后,该怎么回收呢?下面介绍。一共四种,前面三种是铺垫,最后一种才是JVM真正使用的

(1)标记-清除

策略:直接把标记为垃圾对象的对应的内存回收,已经回收的内存,其他对象可以使用

缺点:这样做很存在内存碎片问题,后续就很难申请到一大块连续的空间

(2)复制算法

策略:要删除空间1中abcd中的ac,就直接将bd复制到另一块空间中

缺点:严重浪费空间。比如有8G内存,就只能使用4G

(3)标记-整理

策略:把不需要释放的内存空间覆盖到需要释放的空间上。可以解决内存碎片问题

缺点:时间开销很大

(4)分代回收

策略:根据不同的场景,采取不同的回收策略,这里的回收策略也就是上述介绍到的。

如何根据场景呢?就是要根据时间来,哪个时间呢?就是对象的年龄。

因为GC主要回收的地方就是堆区,所以堆区上会有对应的分区,不同的区代表对象的年龄

Eden:称为伊甸区,新创建的对象都处于这里。

这里的对象生命周期都很短,一般经过一轮GC就会成为垃圾。从伊甸区到达生存区,采取的是复制算法

s0:称为生存区,一般经过一轮还未被回收,就会到达下一个阶段

从生存区到达幸存区,也是通过复制算法

s1:称为幸存区

这里也称为生存区,到达这里也需要通过复制算法。

Old区:到达这里的对象都会成为老年代的对象,GC的扫描频率会大幅度降低。

对于老年代中的垃圾,就会通过标记-整理的方法进行回收

总结一下:伊甸区、生存区、幸存区都是通过复制算法回收垃圾很搬运到下一个区,对于老年区,则是通过标记-整理回收垃圾。

相关文章:

八股文之JVM

目录 1.JVM内存划分 2.JVM类加载过程 3.JVM垃圾回收机制GC 3.1.判断谁是垃圾 3.2.如何释放对应的内存 1.JVM内存划分 在一个Java程序运行起来之后,jvm就会从操作系统中申请一块内存,然后就会将该内存划分成多个部分,用于不同的用途。 …...

给wordpress添加限制游客浏览数量功能

wordpress游客只可以浏览5个内容,其它更多的是的需要注册后才能浏览。以下是使用自定义代码来实现这一功能的基本步骤: 创建一个自定义角色: 使用wp_create_roles函数来创建一个名为“访客”的新角色。 该角色将只具有阅读权限。 限制文章…...

[二分枚举]特殊密码锁

描述 有一种特殊的二进制密码锁&#xff0c;由n个相连的按钮组成&#xff08;n<30&#xff09;&#xff0c;按钮有凹/凸两种状态&#xff0c;用手按按钮会改变其状态。 然而让人头疼的是&#xff0c;当你按一个按钮时&#xff0c;跟它相邻的两个按钮状态也会反转。当然&am…...

MT1434 找数字

题目 输入一个字符串(包含26个英文字母大小写及 . 空格&#xff0c;不含其他字符)&#xff0c;把其中连续的数字作为一个整数&#xff0c;依次存放到一个数组中&#xff0c;输出这些整数的和。 格式 输入格式 输入字符串 输出格式 输出整型 样例1 输入&#xff1a; a12…...

2024年6月四六级考试复盘

一、考试情况 1.1四级考试情况 听力&#xff1a;一开始没有进入状态。总共对了9道。7.1*37.1*314.2*3 8.2 新闻听力&#xff1a;3/7 长对话&#xff1a;3/8 讲座/讲话&#xff1a;3/10 阅读&#xff1a;3.55*7 7.1*8 14.2 * 7 181.05 选词填空&#xff1a;保守估计7/1…...

join和left join性能比较

1、join和left join性能比较&#xff08;AI生成&#xff09; 在MySQL中&#xff0c;JOIN和LEFT JOIN的效率并不是绝对的&#xff0c;它们之间的性能差异取决于多种因素&#xff0c;如表的大小、使用的索引、查询的复杂性等。 一般来说&#xff1a; 如果两个表之间的连接条件能…...

Qt正则表达式

需求&#xff1a;对输入的内容进行限制 只能以字母或下划线开始不能以数字开始 不能有中文 字母&#xff0c;数字&#xff0c;下划线混合使用 QRegExp rx("^[A-Za-z_][A-Za-z0-9_]*$");QRegExpValidator validator(rx);QLineEdit edit;edit.setValidator(&va…...

排序-快排算法对数组进行排序

目录 一、问题描述 二、解题思路 1.初始化 2.将右侧小于基准元素移到左边 3.将左侧大于基准元素移到右边 4.重复执行上面的操作 5.对分好的左、右分区再次执行分区操作 6.最终排序结果 三、代码实现 四、刷题链接 一、问题描述 二、解题思路 快排算法实现数组排序&am…...

flink学习-容错机制

checkpoint&#xff08;检查点&#xff09; 在flink中最重要的容错机制&#xff0c;就是checkpoint机制&#xff0c;使用checkpoint可以将之前某个时间点的所有的状态进行保存&#xff0c;这个存档就是checkpoint。 检查点的保存 周期性存储保存&#xff0c;间隔时间可以由用…...

InfluxDB技术分享

InfluxDB是一个开源的时间序列数据库&#xff0c;它被设计用来处理高速写入和查询大量的时间序列数据。以下是一份关于“InfluxDB在Java开发中的使用”的三十分钟技术分享内容概要&#xff1a; 1. 引言 (2分钟) 介绍时间序列数据和时间序列数据库的概念。引入InfluxDB的特点和…...

Windows10安装配置Docker客户端和WSL2与Hyper-V虚拟机

一、需求说明 需要在Windows系统中安装配置Docker的客户端,方便直接管理配置docker镜像容器内容。 二、Windows10安装Docker客户端步骤 2.1、下载安装Docker客户端 对于Windows 10以下的用户,推荐使用Docker Toolbox Windows安装文件:http://mirrors.aliyun.com/docker-…...

EIQ-ABC 分析法在配送中心储位分配中的应用

配送中心运作效率的高低主要取决于仓储业务流程的作业效率&#xff0c;在配送作业流程中&#xff0c;储位分配的是否合理性成为影响配送运作效率的重要因素。为实现储位的合理分配&#xff0c;提出通过对订单信息的分析&#xff0c;并应用 EIQ-ABC 分析法&#xff0c;以此实现缩…...

【安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试】

安装笔记-系列文章目录 安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试 文章目录 安装笔记-系列文章目录安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试 前言一、软件介绍名称&#xff1a;ttyd主页官方介绍特点 二、安装步骤测试版本&#xf…...

React小记(一)_基础部分

1、项目搭建与结构 2、类组件和函数组件 主要区别&#xff1a;1、函数组件没有生命周期2、函数组件没有this指向3、函数组件没有状态4、函数组件通过hooks实现各种操作5、props在函数的第一个参数接收6、函数体相当于类组件的render函数import React from reactfunction App()…...

40、基于深度学习的线性预测设计(matlab)

1、原理及流程 深度学习的线性预测是一种利用深度神经网络模型进行线性回归预测的方法。其设计原理主要基于神经网络的层次化特性&#xff0c;利用多层感知器&#xff08;MLP&#xff09;等模型进行特征学习和非线性变换&#xff0c;从而提高线性预测的准确性。 设计流程如下…...

【初体验 threejs】【学习】【笔记】hello,正方体 3!

前言 为了满足工作需求&#xff0c;我已着手学习 Three.js&#xff0c;并决定详细记录这一学习过程。在此旅程中&#xff0c;如果出现理解偏差或有其他更佳的学习方法&#xff0c;请大家不吝赐教&#xff0c;在评论区给予指正或分享您的宝贵建议&#xff0c;我将不胜感激。 项…...

第04章:IDEA的安装与使用

第04章&#xff1a;随堂复习与企业真题&#xff08;IDEA安装与使用&#xff09; 一、随堂复习 1. IDEA的认识 IDEA(集成功能强大、符合人体工程学&#xff08;设置人性化&#xff09;)Eclipse 2. IDEA的下载、安装、卸载 卸载&#xff1a;使用控制面板进行卸载&#xff0c;…...

[原创][Delphi多线程]使用TMonitor, TEvent和TQueue配合实现TThreadQueue的经典使用案例.

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delph…...

6.12ctf练习

[西湖论剑 2022]Node Magical Login 源码在这里&#xff1a;GitHub - CTF-Archives/2022-xhlj-web-node_magical_login: A web challenge in 2022 西湖论剑大赛打开 打开环境是个登录框&#xff0c;先进行了扫描和抓包都没有看见什么有价值的东西&#xff0c;看源码 大致连接…...

海豚调度异常处理: 使用 arthas 在内存中删除启动失败的工作流

&#x1f4a1; 本系列文章是 DolphinScheduler 由浅入深的教程&#xff0c;涵盖搭建、二开迭代、核心原理解读、运维和管理等一系列内容。适用于想对 DolphinScheduler了解或想要加深理解的读者。祝开卷有益。大数据学习指南 大家好&#xff0c;我是小陶&#xff0c;DolphinSch…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...