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

Java:JVM

1.JVM内存区域的划分

一个Java写的程序跑起来,就得到了一个Java进程 = JVM + 上面运行的字节码指令;

进程:操作系统资源分配的基本单位;

内存区域的划分:

1.程序计数器

在内存空间里(比较小的空间),保存了下一个要执行的指令的内存地址(元数据区的地址);

这里的"下一条要执行的指令"是Java的字节码(不是CPU的二进制机器语言);

2.堆

JVM上最大的空间, new出来的对象都在堆上;

3.栈

函数中的局部变量,函数的形参,函数之间的调用关系;

分为Java虚拟机栈(JVM之上,运行的Java代码的函数调用关系)本地空间栈(JVM里头C++代码的函数调用关系);

4.元数据区(方法区)

Java程序中的指令.指令都是包含在类的方法中的;

保存了代码中涉及到的类的相关信息; 类的static属性也被包含在其中;

---------------------------------------------------------------------------------------------------------------------------------

在一个Java进程中,元数据区和堆是只有一份的.

程序计数器和栈则可能有多份;

当一个Java进程中有多个线程的时候,每个线程都有自己的程序计数器和栈,线程就代表一个"执行流";

---------------------------------------------------------------------------------------------------------------------------------

代码中的变量都处在上述的哪个区域呢?

一个变量处在哪个内存区域,和变量是不是"内置类型"无关,而是和变量的形态有关;

(1)局部变量 -> 栈;

(2)成员变量 -> 堆;

(3)静态成员变量 -> 元数据区(方法区);

---------------------------------------------------------------------------------------------------------------------------------

2.JVM类加载的过程

Java程序 -> .java文件;

javac编译 -> .class文件;

运行Java进程的时候,JVM就要读取.class里面的内容,并且执行里面的命令;

读取.class内容的过程就是类加载的过程.

把类涉及到的字节码从硬盘读取到内存中(元数据区).

加载一个.class文件,就会用.class里的指令创建一个类对象.

类对象中就包含了.class文件中的各种信息,基于类对象就能创建该类的实例;

比如:类的名字;

类有哪些属性,属性名是什么,每个属性类型是什么:public/private;

类有哪些方法,每个方法名是什么,参数是什么,方法的类型:public/private;

继承的父类有哪些,实现的接口有哪些...

因为有了类对象,才能进行反射,反射的api都是从类对象中获取信息的;

类加载的输入:.class文件(类的全限定名);

类加载得到的结果:内存中对应的类对象;        

---------------------------------------------------------------------------------------------------------------------------------

类加载的具体步骤

1.加载

把.class文件找到; 在代码中先见到类的名字,然后进一步的找到对应的.class文件.

打开并读取文件内容;

---------------------------------------------------------------------------------------------------------------------------------

2.验证

验证读到的.class文件中的数据是否正确,是否合法;

Java标准文档中,明确定义了.class文件的格式是怎么样的;

magic:计算机圈子约定俗成的做法.

二进制文件,会在开头的若干个字节,设置一个固定的常数进去;

通过这个常数,标识当前这个文件是啥样的文件.

minor_version/major_version:需要确保编译时使用的JDK和运行时使用的JDK版本一致;

JDK是可以向前兼容的(使用Java8的JDK编译出的.class文件放到Java17一般是可以运行的)

---------------------------------------------------------------------------------------------------------------------------------

3.准备

分配内存空间;

最终需要得到类对象 -> 需要内存;

根据刚才读取到的内容,确定出类对象所需要的内存空间,申请这样的内存空间,

并且把内存空间中所有的内容,都初始化为0;

(Java创建一个内存空间,都会把这个内存空间全设为0,后续再进一步初始化;

C/C++则不会进行置零操作,此时内存上对应的数据是上次使用残留的)

---------------------------------------------------------------------------------------------------------------------------------

4.解析

主要是针对类中的字符串常量进行处理;

解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程.

有很多其他的指令使用"hello"字符串常量,在文件中,这些指令就会使用"偏移量"表示"hello"字符串;

---------------------------------------------------------------------------------------------------------------------------------

5.初始化

针对类对象做最终的初始化操作;

执行静态成员的赋值语句;

执行类中的静态代码块;

针对父类也要进行加载(如果当前加载的类有父类,并且父类还没有被加载,这个环节也会触发对父类的加载);

---------------------------------------------------------------------------------------------------------------------------------

双亲委派模型

更准确应该叫单亲委派模型/父亲委派模型;

类加载五个部分,第一个步骤中里面的一个环节;

给定类的全限定名,找到对应的class文件的位置;

---------------------------------------------------------------------------------------------------------------------------------

类加载器:JVM中的功能模块,JVM中,已经内置了一些类加载器完成上述的"类加载"过程;

JVM默认有三个类加载器:

BootstrapClassLoader;(爷爷)

负责加载标准库的类;(标准库类,有一个专门的存放位置)

ExtensionClassLoader;(爸爸)

负责加载一些扩展类;(JVM厂商,希望对Java的功能做出一些扩展)

ApplicationClassLoader;(儿子)

负责加载第三方库中的类/自己写的代码的类; 

注意:

这里的父子关系不是Java中父类子类这样的继承关系;

每个类加载器有个parent这样的引用指向父亲;

---------------------------------------------------------------------------------------------------------------------------------

双亲委派模型的工作流程:

输入:类的全限定名(字符串),类似于java.lang.String

得到:找到对应的.class文件.

请求先会一直向上传递,若父亲没有找到,请求才会交给儿子;

若在某一加载器找到了,请求就结束了,就会执行类加载2345步骤;

如果都没有找到,就会抛出异常ClassNotFoundException;

这样模型的目的就是:防止用户自己写的类,把标准库的类覆盖掉.

保证标准库的类,被加载的优先级是最高的,标准库其次,第三方库优先级最低;

---------------------------------------------------------------------------------------------------------------------------------

3.JVM的垃圾回收机制(GC)

C/C++中,malloc/new一个对象,都需要手动释放内存free/delete,如果不释放就会造成内存泄露;

垃圾回收机制就是为了让程序员可以放心大胆的new对象,防止内存泄漏问题;

GC也是有代价的,需要消耗一定的性能,进行GC的时候可能会触发STW问题(Stop The World)导致程序卡顿,故C/C++没有引入GC;

GC需要负责回收的区域有哪些:

1.程序计数器/栈:

都是跟随线程的,不需要GC.

2.堆:

GC回收的主战场,

3.元数据区:

类对象->类加载,一个程序中要加载的类都是有上线的.不会出现无限增长,内存泄漏的情况;

---------------------------------------------------------------------------------------------------------------------------------

GC是如何进行回收的:

以对象为维度进行回收的.

---------------------------------------------------------------------------------------------------------------------------------

1.先找出谁是垃圾.

需要针对每个对象分别判定.

方案一:引用计数(Java没有采纳)

在Java中使用对象一般都是通过"引用"来实现的;

如果一个对象如果没有引用指向了,就可以认为这个对象是垃圾了;

给每个对象分配一个计数器,衡量有多少个引用指向,

每次增加一个引用,计数器+1; 每次减少一个引用,计数器-1;

当计数器减为0,此时这个对象就是垃圾了;

 在JVM中并没有采纳,Python/PHP使用这种方案;

存在以下两个问题:

(1)消耗额外的空间;

(2)引用计数可能会导致"循环引用"使得上述的判定出错;(需要引入"环路检测"机制来解决,代价更大了)

---------------------------------------------------------------------------------------------------------------------------------

方案二:可达性分析(Java采用的方案)

用时间换空间;

在JVM中,专门搞了一波线程,周期性的扫描代码中的所有对象,判断某个对象是否"可达"(可以被访问到)

对应的,"不可达"的对象就是垃圾了;

可达性分析的起点叫做GC root;

一个程序中不是只有一个GC root, 而是有很多个;

哪些变量可以作为GC root 呢:

(1)栈上的局部变量(引用类型);

(2)方法区中,静态的成员(引用类型);

(3)常量池中引用指向的对象;

把所有的GC root都遍历一遍 ,针对每一个尽量往下延伸;

---------------------------------------------------------------------------------------------------------------------------------

2.释放垃圾的内存空间.

方案一:标记-清除方法

针对内存中的对应对象进行释放:

这样的做法,会引入"内存碎片问题":

很可能要释放的多个内存,不是连续的,

虽然把上述内存释放掉,但是整体上这些释放掉的空间并没有连在一起;

后续申请内存空间的时候就可能申请不了,因为申请的内存是连续的;

---------------------------------------------------------------------------------------------------------------------------------

方案二:复制算法

同一时刻只使用内存的其中一半:

把不是垃圾的对象都拷贝到内存的另一侧,然后把存放垃圾的这一半内存全部释放掉;

缺点:

1.内存空间利用率低;

2.如果存活下来的对象比较多,复制成本也比较大;

方案三:标记-整理方法

---------------------------------------------------------------------------------------------------------------------------------

非常类似于顺序表删除中间元素的过程;

缺点:搬运的开销也比较大;

---------------------------------------------------------------------------------------------------------------------------------

方案四:分代算法(JVM采取的方法)

把上述几个方案综合一下,取长补短;

JVM根据对象的年龄(根据周期性的可达性分析来计算年龄),把对象进行区分:

新生代:一般创建的对象都会进入新生代;

老年代:大对象和经历了 N 次(⼀般情况默认是 15 次)垃圾回收依然存活下来的对象会从新生代

移动到老年代.

刚创建的对象就处在伊甸区(比较大);

根据经验规律,绝大部分对象是活不过第一轮GC的,

留存下来的对象,就会被拷贝到幸存区(比较小,内存浪费少);

幸存区是两个相等的空间,按照复制算法进行处理;

反复进行多次...

当对象年龄不断增长就会被放到老年代的区域;

根据经验规律,老年代的对象,生命周期比较长;

对于老年代,进行GC的频率就会降低,另外老年代是通过标记整理方法来回收(次数比较少,时间开销浪费也少);

---------------------------------------------------------------------------------------------------------------------------------

垃圾回收器

"分代回收"是JVM的GC中的基本思想方法.

具体落实到JVM实现层面上,JVM还提供了多种的"垃圾回收器";

对上述的分代回收做进一步的拓展和实现;

关注CMS/G1即可

CMS

把整个GC过程拆成多个阶段,能和业务线程并发执行的就尽量并发,

尽可能减少STW的时间;

G1

把整个内存分成很多块,不同的颜色/字母表示这是新生代(伊甸区/幸存区)/老年代;

进行GC的时候,不要求一个GC就把所有的内存都回收一边,而是一轮GC只回收其中的一部分;

限制一轮GC花的时间/工作量,使STW的时间在可控范围内;

相关文章:

Java:JVM

1.JVM内存区域的划分 一个Java写的程序跑起来,就得到了一个Java进程 JVM 上面运行的字节码指令; 进程:操作系统资源分配的基本单位; 内存区域的划分: 1.程序计数器 在内存空间里(比较小的空间),保存了下一个要执行的指令的内存地址(元数据区的地址); 这里的"下一条…...

Windows下mysql数据库备份策略

Windows下mysql的增量备份和全量备份,并利用schtasks设置定时任务执行bat脚本。 一、备份要求 序号 备份类型 备份频次 备份时间 1 增量备份 每周一-每周六各一次 18:00:00 2 全量备份 每周日一次 18:00:00 二、备份方法 2.1增量备份 2.1.1准备工作…...

基于SSM的校园美食交流系统【附源码】

基于SSM的校园美食交流系统 效果如下: 管理员主页面 用户主页面 美食信息页面 美食资讯页面 修改密码页面 论坛中心页面 研究背景 随着高校信息化建设的不断推进,校园生活日益丰富多样,学生对于美食的需求与探索也愈发旺盛。然而&#xff…...

2024 年Postman 导入和导出 cURL 命令图文教程

Postman 导入和导出 cURL 命令图文教程...

ArcGIS从Excel表格文件导入XY数据并定义坐标系与投影的方法

本文介绍在ArcMap软件中,从Excel表格文件中批量导入坐标点数据,将其保存为.shp矢量格式,并定义坐标系、转为投影坐标系的方法。 已知我们有一个Excel表格文件(可以是.xls、.xlsx、.csv等多种不同的表格文件格式)&#…...

【vue】echarts地图添加蒙版图片,多图层地图实现天气信息展示

实现原理&#xff1a;多层图层叠加实现复杂的信息展示。 <template><div class"wrapper"><el-drawertitle"天气信息":modal"iszz":visible.sync"weatherinfo":direction"direction"><drawer:labelnam…...

MyBatis几种SQL写法

目录 1. 批量操作:通过标签支持批量插入 2. 批量操作:通过标签支持批量更新 3. 批量操作&#xff1a;通过标签支持批量删除 4. 动态SQL 3. 多条件分支查询 4. SQL语句优化&#xff1a;使用标签避免多余的AND或OR关键字。 5. 注解方式使用MyBatis 6. 一对多 7. 多对一&…...

蓝牙音响音频功放:【矽源特HAA9809 AB+D类自动切换】

目录 1&#xff1a;HAA9809特性 2&#xff1a;典型应用电路 3&#xff1a;CTRL管脚控制信息 4&#xff1a;一线脉冲控制方式 5&#xff1a;输入电阻&#xff0c;调节放大增益 6&#xff1a;输入电容&#xff0c;调节频响 7&#xff1a;总结 矽源特ChipSourceTek-HAA9809…...

Webpack知识点—publicPath

文章目录 一、publicPath的定义和作用二、publicPath的配置方式三、publicPath的注意事项四、publicPath的常见问题和解决方法五、Vite 如何修改publicPathWebpack的publicPath是一个重要的配置项,它用于指定打包后生成的静态资源文件在浏览器中的访问路径。 一、publicPath的…...

【JAVA】Java基础—面向对象编程:构造方法的重载

在Java中&#xff0c;构造方法的重载允许一个类定义多个构造方法&#xff0c;这些构造方法可以具有不同的参数列表。通过构造方法的重载&#xff0c;我们可以根据不同的需求创建对象&#xff0c;并以不同的方式初始化对象的属性。 我们可以将构造方法的重载比作一个餐厅的菜单…...

科研绘图系列:R语言多图形组合(barplot boxplot stacked plots)

文章目录 介绍加载R包数据下载图:Barplot图:Boxplot per elemental composition图:网络的边数目图:Clusters - elemental composition合并图形系统信息介绍 R语言多个图形组合 加载R包 library(tidyverse) library(ggpubr) library(rstatix) library(patchwork)数据下载…...

诡异的win11远程桌面连接一闪而过

客户端win10&#xff0c;服务器端是win2019 上面的仅允许允许使用网络级别身份验证的也勾掉了。 mstsc和mstsc -admin远程桌面连接&#xff0c;输入ip点连接后闪退&#xff0c;根本不弹出用户密码输入。但有人也是win10却可以连&#xff0c;也不知道自己的win10有啥差异的地方。…...

基因组编辑与CRISPR技术:基因治疗的革命性突破

引言 基因组编辑技术的出现&#xff0c;尤其是CRISPR-Cas9技术的问世&#xff0c;极大地推动了生物医学研究和基因治疗的发展。这一技术不仅为基础科学研究提供了强大的工具&#xff0c;也为治疗遗传性疾病、癌症以及某些病毒感染开辟了新的治疗思路。基因组编辑技术可以精准地…...

智能检测技术与传感器(热电传感器四个定律)

热电传感器&#xff1a; 两种不同的导体两端相互紧密地连接在一起&#xff0c;组成一个闭合回路。当两接点温度不等时&#xff08;设 &#xff09;&#xff0c;回路中就会产生大小和方向与导体材料及两接点的温度有关的电动势&#xff0c;从而形成电流&#xff0c;这种现象称为…...

C# WPF FontDialog字体对话框,ColorDialog颜色对话框 引用

WPF 并没有内置FontDialog和ColorDialog&#xff0c;但可以通过引用 Windows Forms 的控件来实现字体和颜色选择对话框功能。FontDialog 允许用户选择字体、样式、大小等设置。 添加 Windows Forms的引用 项目工程&#xff1a;右键“引用”》“添加引用”》勾选System.Window…...

在unity中实现把普通的照片,图片 变成油画风格的shader实现

可以通过对shader的Radius的值得设置来改变油画风格的力度&#xff0c;0最小&#xff0c;10是最大。...

使用elementUI实现表格行拖拽改变顺序,无需引入外部库

前言&#xff1a; 使用vue2element UI&#xff0c;且完全使用原生的拖拽事件,无需引入外部库。 如果表格数据量较大&#xff0c;或需要更多复杂功能&#xff0c;可以考虑使用 vuedraggable库&#xff0c;提供更多配置选项和拖拽功能。 思路&#xff1a; 1. 通过el-table的ro…...

PySpark 数据处理实战:从基础操作到案例分析

Spark 的介绍与搭建&#xff1a;从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交&#xff1a;本地与集群模式全解析-CSDN博客 Spark on YARN&#xff1a;Spark集群模式…...

恒源云使用手册记录:从服务器下载数据到本地

文章目录 一、xftp下载二、通过Xftp客户端连接站点 一、xftp下载 先下载xftp&#xff1a;下载连接 二、通过Xftp客户端连接站点 右击文件&#xff0c;点击新建 名称可以任意 主机、端口号、用户名 点击这里的复制登录命令 比如我这里得到ssh -p 41604 rooti-2.gpushare.co…...

【大咖云集 | IEEE计算智能学会广州分会支持】第四届信息技术与当代体育国际学术会议(TCS 2024,12月13-15日)

第四届信息技术与当代体育国际学术会议&#xff08;TCS 2024&#xff09; 2024 4th International Conference on Information Technology and Contemporary Sports 重要信息 会议官网&#xff1a;www.icitcs.net&#xff08;会议关键词&#xff1a;TCS 2024&#xff09; 202…...

【AI声音克隆整合包及教程】第二代GPT-SoVITS V2:技术、应用与伦理思考

一、引言 在当今科技迅速发展的时代&#xff0c;声音克隆技术成为人工智能领域的一个备受瞩目的分支。GPT-SoVITS V2作为一种声音克隆工具&#xff0c;正逐渐进入人们的视野&#xff0c;它在多个领域展现出巨大的潜力&#xff0c;同时也引发了一系列值得深入探讨的问题。本文旨…...

利用AI制作《职业生涯规划PPT》,10分钟完成

职业生涯规划是大学生活中非常重要的一环。通过制定职业规划&#xff0c;你能够明确未来的职业目标、认清自身的优劣势&#xff0c;进而制定切实可行的计划&#xff0c;以便顺利踏上职业发展的道路。而制作一份精美的职业生涯规划PPT&#xff0c;能有效帮助你在面试、职业规划报…...

【Java多线程】线程安全及解决方案(详解)

目录 线程安全问题引入&#xff1a; 线程安全原因 如何解决线程安全问题&#xff1f; &#xff08;1&#xff09;synchronized关键字 1)sychronized关键字的特性: 2)可重⼊ synchronized使⽤⽰例 &#xff08;2&#xff09;volatile关键字 1&#xff09;内存可见性和…...

【前端基础】Javascript取整函数以及向零取整方式

向零取整方式 在JavaScript中&#xff0c;有多种方式可以对数字进行取整操作&#xff0c;即去掉小数部分&#xff0c;只保留整数部分。其中&#xff0c;向0取整&#xff08;也称为截断小数部分&#xff09;的方式有以下几种常用的方法&#xff1a; 使用 Math.trunc()&#xff…...

禅道与Jira与Ones对比:哪个更适合你的项目管理需求?

一、项目管理工具的重要性 在当今复杂的项目环境中&#xff0c;选择合适的项目管理工具对项目成功至关重要。随着项目规模的不断扩大、涉及领域的日益广泛以及团队成员的分散性&#xff0c;传统的项目管理方式已经难以满足需求。 项目管理工具可以帮助团队更好地规划和组织项…...

Linux I/O编程:I/O多路复用与异步 I/O对比

文章目录 0. 引言1. I/O 模型简介1.1 阻塞 I/O&#xff08;Blocking I/O&#xff09;1.2 非阻塞 I/O&#xff08;Non-Blocking I/O&#xff09;1.3 信号驱动式 I/O&#xff08;Signal-Driven I/O&#xff09;1.4 多路复用 I/O&#xff08;I/O Multiplexing&#xff09;1.5 异步…...

Spark Plan 之 SQLMetric

SQLMetric Spark Plan 包含以下基本 方法&#xff0c; /*** return All metrics containing metrics of this SparkPlan.*/def metrics: Map[String, SQLMetric] Map.empty/*** return [[SQLMetric]] for the name.*/def longMetric(name: String): SQLMetric metrics(name)…...

基于YOLOv5模型的火焰识别系统

大家好&#xff0c;YOLOv5模型能够快速准确地检测到火灾火焰&#xff0c;在火灾初期甚至是刚刚出现火苗时就发出警报。这为及时采取灭火措施争取了宝贵的时间&#xff0c;极大地降低了火灾造成的损失。系统可以对特定区域进行持续实时监测&#xff0c;无论白天还是夜晚&#xf…...

多模态AI:开启人工智能的新纪元

在人工智能的璀璨星河中&#xff0c;多模态AI技术正逐渐成为一颗耀眼的明星。随着科技的飞速发展&#xff0c;AI技术正以前所未有的速度迈向新的高峰&#xff0c;其中多模态AI的兴起尤为引人注目。本文将深入探讨多模态AI的定义、技术原理、应用场景以及未来发展趋势。 ps.图…...

麒麟信安支撑2024年电力监控系统网络安全加固培训护航电力网络安全!

在网络安全形势日益复杂的今天&#xff0c;电力行业的网络安全尤为重要。为提升电力监控系统网络安全运维人员的专业技能&#xff0c;由国调中心网安处精心策划&#xff0c;国家电网技术学院组织开展的“2024年电力监控系统网络安全加固培训”于近日圆满结束。麒麟信安作为重要…...

微信公众号做微网站吗/app推广软件有哪些

今天在Windows上配置了下nginx&#xff0c;看了不少其他大牛们记录的博客&#xff0c;自己也操作了一番&#xff0c;记录一下备忘。 nginx download: http://nginx.org/en/download.htmlphp download: http://php.net/windows下nginxphp的安装配置如下&#xff1a;1、安装php(D…...

wordpress调用网页/沈阳沈河seo网站排名优化

解决方案&#xff1a;1&#xff0c;最傻瓜也最方便的处理方式&#xff0c;运行新的容器前设置本机时区和时间文件与容器的映射docker run -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime ...1-v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localt…...

企业电子商务网站开发实训目的/网页怎么优化

MyEclipse 2015 stable 3.0 详细安装图解与注册方法 ---------------------------------- 声明&#xff1a;仅供学习交流测试&#xff0c;严禁用于商业用途&#xff0c;请于24小时内删除&#xff01; MyEclipse是一款非常优秀的Java开发IDE工具&#xff0c;最新版的已经有My…...

网站建设的概念/网站建设技术托管

展开全部回答不能插入代码格式&#xff0c;比较乱。e68a843231313335323631343130323136353331333433633433我截图给你看吧。package com.test;import javax.swing.*;import java.awt.*;public class DrawTest extends JFrame {public static void main(String[] args) {DrawTe…...

新的网站的建设步骤/sem和seo的区别

一&#xff0c;事件 事件&#xff08;event&#xff09;是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘&#xff0c;或者是窗口需要重新绘制的时候&#xff0c;都会发出一个相应的事件。一些事件在对用户操作做出响应时发出&#xff0c;如键盘事件等&#…...

wordpress图片上传到哪里/搜索引擎谷歌入口

...