JVM的组成部分(类加载器、运行时数据区、执行引擎、本地库接口)

目录

JVM作用

JVM构成 

1.类加载器

类加载子系统:

类加载器的分类:

双亲委派机制:

2.运行时数据区

程序计数器

虚拟机栈

本地方法栈

方法区

3.执行引擎

4.本地库接口


JVM作用

jvm是将字节码文件加载到虚拟机中,再将字节码文件编译/解释成机器码。

管理运行时的数据存储和垃圾回收,现在的jvm还可以执行其他语言的字节码

JVM构成 

1.类加载器

将硬盘上的字节码文件加载到jvm上

类加载子系统:

类加载过程:

✔️加载

以二进制的形式加载字节码;

在内存中为类生成一个class对象,将静态存储转为动态存储。

✔️链接

1.验证:

  • 验证class文件的格式是否正确,class文件在文件开头有特定的文件标识(字节码文件都以CA FE BA BE 标识开头)。
  • 元数据验证:验证语法是否正确。

2.准备

  • 为类的静态属性分配内存,并设置默认初始值,例如:   

           public static int a = 10;   准备阶段后的值是0,而不是10,初始化阶段才为10;

注意:final修饰的static变量在编译时进行初始化。

3.解析

将静态文件中的指令符号引用  替换成 内存直接引用

✔️初始化

为类变量(静态变量)赋予正确的值

类加载器的分类:

类加载器:真正实现类加载的具体实现者

✔️JVM角度(宏观)

  • 引导类加载器(启动类加载器):不是用java语言实现的,c/c++ JVM底层实现
  • 其他所有类加载器:用java语言写的实现类,都继承java.lang.ClassLoader

 ✔️开发者角度(微观)

引导类加载器 :

java中系统提供的类,都是由启动类加载器加载,例如String

扩展类加载器 :

java语言编写的,由sun.misc.LauncherAppClassLoader实现,

派生于ClassLoader类

jre/lib/ext子目录(扩展目录)下加载类库

应用程序类加载器 :

java语言编写的,由sun.misc.LauncherAppClassLoader实现。

派生于ClassLoader类

加载我们自己定义的类,用于加载用户类路径(classpath)上所有的类

自定义类加载器 :

例如我们自己写一个集成ClassLoader

再例如Tomcat这种容器,都会有自己加载类的加载器

双亲委派机制:

当加载一个类的时候,先让上一级的类加载去加载,直到找到引用类加载器;

如果上级类加载器找到了,就是要上级类加载器加载我的类,

如果找不到,就逐级向下委托,使用子级类加载器加载我的类,

如果都找不到就报异常。

public class ClassLoaderDemo {public static void main(String[] args) throws ClassNotFoundException {//类加载器为null,说明是引导类加载器加载的System.out.println(String.class.getClassLoader());//我们的类是由sun.misc.Launcher$AppClassLoader@18b4aac2,应用程序类加载的System.out.println(ClassLoaderDemo.class.getClassLoader());//sun.misc.Launcher$ExtClassLoader@1b6d3586 应用程序类是由扩展类加载的System.out.println(ClassLoaderDemo.class.getClassLoader().getParent());//扩展类加载器是由引导类加载器加载的System.out.println(ClassLoaderDemo.class.getClassLoader().getParent().getParent());}
}

 输出结果:

双亲委派机制测试:当创建一个自己的String类,调用其中的类变量,由于双亲委派机制,java核心类库会创建String对象,而不会使用我们自己创建的String的类,因此报错。

 双亲委派机制的优点

安全,避免改变java核心类。

如何打破双亲委派机制?

在 ClassLoader 类中涉及类加载的方法有两个,loadClass(String name), findClass(String name),这两个方法并没有被 final 修饰,也就表示其他子类可以,重写 findClass 方法。
我们可以通过自定义类加载重写方法打破双亲委派机制, 再例如 tomcat 等都有自己定义的类加载器。

2.运行时数据区

运行时数据区组成:

程序计数器

作用:用来存储下一条指令的地址,由执行引擎读取下一条指令。

特点:

是一个很小的内存空间,但是运行速度最快的存储区域;

  • 是线程私有(每个线程都会有自己的计数器);

  • 生命周期与线程一致;

  • 不会出现内存溢出(唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域),不会有垃圾回收。

虚拟机栈

栈是运行单位,管理方法(java自己写的方法)运行;

调用方法入栈,运行出栈;

栈是线程私有的,存在内存溢出可能,不存在垃圾回收;

一个线程就是一个栈;

一个方法入栈后,可以看做是一个栈帧。

访问速度仅次于程序计数器。

栈帧:

局部变量表:存储方法中定义的变量

操作数栈:表达式计算

方法返回地址:与返回值无关

本地方法栈

作用:管理本地方法的调用

本地方法是线程私有的,不会有垃圾回收,是用c语言写的,用native关键字修饰;

如果线程请求分配的栈容量超过本地方法栈允许的最大容量抛出StackOverflowError(内存溢出)。

常见的本地方法:

Object中:

hashCode() 内存地址

getClass()

clone()                               

notiy(),唤醒,wait(),otiyAll()

FileInputStrem中:

native int read()

Thread

native void start0()

存放程序中产生的对象

JVM管理的最大一块内存空间

大小可以调节

线程共享

会出现内存溢出,会进行垃圾回收

堆空间有区域划分,为什么要进行划分?

新生代:

伊甸园区:刚刚创建的对象存放在伊甸园区

幸存者0:伊甸园剩余的对象和幸存者1中的对象

幸存者1:幸存者1中的对象

老年代:

存放生命周期长的/非常大的对象

经历过15次回收后依然存活的对象,将放在老年代

为什么要分区:

可以根据不同对象的存活时间进行划分

生命较长的对象放在老年区,减少垃圾回收的频率和扫描次数

对象创建以及在内存分布过程:

1.新创建的对象放在伊甸园区

2.当垃圾回收时,将伊甸园存活的对象移入到幸存者0区

3.继续运行,再次创建的对象还是保存到伊甸园区

4.下一次垃圾回收到来时,将伊甸园区存活的对象和幸存者0区移入到幸存者1区,幸存者0区和幸存者1区保证有一个为空。

5.当一个对象经历过15次垃圾回收后仍然存活,那么就将此对象移入到老年代,在对象头中4个bit位用来记录回收次数,可以设置回收次数,但是最大值是15。

老年代:新生代比例=2:1

伊甸园和两个幸存者比例=8:1:1

堆空间的参数设置:官网:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html​​​​​​​

-XX:+PrintFlagsInitial 查看所有参数的默认初始值

-Xms:初始堆空间内存

-Xmx:最大堆空间内存

-Xmn:设置新生代的大小

-XX:MaxTenuringTreshold:设置新生代垃圾的最大年龄

-XX:+PrintGCDetails 输出详细的 GC 处理日志

垃圾回收名词:

Minor GC:主要回收新生代

Major GC:回收老年代

FULL GC:  整堆回收;老年代不足时,方法区空间不足时也会触发堆回收

方法区

主要存储加到jvm中的类的信息

是线程共享的,会出现内存溢出;

方法区包含了一个特殊的区域“运行时常量池”。

方法区垃圾回收,必须同时满足三个条件

1.该类的所有对象以及子类对象都不存在

2.加载该类的加载器不存在了

3.该类的class对象没有被其他地方引用

一般情况下可以认为类是不会被卸载的。

3.执行引擎

作用:将高级语言翻译为机器码,即负责将装在到虚拟机中的字节码 解释/编译为机器码。

 

解释器:当 Java 虚拟机启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容“翻译”为对应平台的本地机器指令执行。

JIT(Just In Time Compiler)编译器:就是虚拟机将源代码一次性直接编译成和本地机器平台相关的机器语言,但并不是马上执行。

前端编译:java-javac----->.class

后端编译:执行引擎----->机器码

解释执行:sql,css,html,js,python,解释器逐行进行解释执行

缺点:效率低,优点:省去编译时间

编译执行:将某段代码进行整体编译,然后执行编译后的结果      

优点:效率更高,缺点:耗时

java是解释执行+编译执行

4.本地库接口

1.本地方法:被native关键字修饰的,不是java语言实现,而是操作系统实现。

2.为什么使用:java环境与外界交互,因为上层的高级语言没有对底层硬件直接操作的权限,而是需要调用操作系统的接口进行调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/640653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年【广东省安全员B证第四批(项目负责人)】新版试题及广东省安全员B证第四批(项目负责人)作业模拟考试

题库来源:安全生产模拟考试一点通公众号小程序 广东省安全员B证第四批(项目负责人)新版试题参考答案及广东省安全员B证第四批(项目负责人)考试试题解析是安全生产模拟考试一点通题库老师及广东省安全员B证第四批&…

一.Winform使用Webview2(Edge浏览器核心) 创建demo(Demo1)实现回车导航到指定地址

Winform使用Webview2创建demo1实现回车导航到指定地址 往期目录参考文档实现1.安装visual studio2.创建单窗口应用3.修改项目中的窗体名称MainForm4.添加按钮5.添加窗口Demo16.在Demo1中添加WebView2 SDK7.在Demo1窗体中选择添加textbox和webview28.在MainForm.cs窗体中添加but…

[ComfyUI进阶教程] lcm+Lora+Controlnet工作流工作流

这是一个使用了LCMlora加载器CN(depthtile)的工作流。 工作流特性: LCM lora加载器,加快生成图片的时间。 配置了3个lora加载器,用来进行人物和风格设定。 提示词编辑器,预制了默认的动态提示词。 使用了…

【RabbitMQ】交换机详解看这一篇就够了

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《RabbitMQ实战》。🎯🎯 &am…

每个人都可以是架构师,每个人都需要培养架构思维

您好, 如果喜欢我的文章或者想上岸大厂,可以关注公众号「量子前端」,将不定期关注推送前端好文、分享就业资料秘籍,也希望有机会一对一帮助你实现梦想 什么是架构 “架构”,即架设、构建。完成对于平台的合理架设&am…

VMware安装Linux-Redhat7.9 详细步骤

目录 一、安装准备二、安装步骤 一、安装准备 Redhat 7.9 镜像下载 VMware安装步骤可查看文章:https://blog.csdn.net/a2279338659/article/details/126346345 可去官网下载,或者加群下载镜像资源。 二、安装步骤 创建新的虚拟机: 我这边…

语音模块学习——LSYT201B模组(深圳雷龙科技)

目录 引子 处理器 外设 音频 蓝牙 模组展示 引子 关注我的老粉们应该知道我之前用过语音模块做东西,那个比较贵要50多。 今天这个淘宝20元左右比那个便宜,之前那个内核是51的,一个8位机。 后面我做东西的时候语音模块可能会换成这个&…

【计算机网络】Socket的TCP_NODELAY选项与Nagle算法

TCP_NODELAY是一个套接字选项,用于控制TCP套接字的延迟行为。当TCP_NODELAY选项被启用时,即设置为true,就会禁用Nagle算法,从而实现TCP套接字的无延迟传输。这意味着每次发送数据时都会立即发送,不会等待缓冲区的填充或…

代码随想录算法训练营DAY24|回溯1

算法训练DAY24|回溯1 第77题. 组合 力扣题目链接 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 上面我们说了要解决 n为100,k为50的情况&#xff0…

vscode连不上虚拟机,一直密码错误

最近在做毕设,但是vscode使用连接不上虚拟机,我以为是网络配置的问题,一顿查阅没找到原因。 后来查了一下ssh的日志,发现ssh有消息,但是也提示密码错误。 没找到密码配置格式什么的,经查看sshd配置文件发现…

工业相机与镜头参数及选型

文章目录 1、相机成像系统模型1.1 视场1.2 成像简化模型 2、工业相机参数2.1 分辨率2.2 靶面尺寸2.3 像元尺寸2.4 帧率/行频2.5 像素深度2.6 动态范围2.7 信噪比2.8 曝光时间2.9 相机接口 3、工业镜头参数3.1 焦距3.2 光圈3.3 景深3.4 镜头分辨率3.5 工作距离(Worki…

微信小程序入门,学习全局配置与页面配置

目录 一、微信小程序 二、微信小程序的全局配置 三、微信小程序的页面配置 四、全局配置与页面配置的区别 一、微信小程序 微信小程序是一种基于微信平台的应用程序,它可以在微信内部直接运行,无需下载安装。微信小程序具有以下特点和优势&#xff…

Spring Boot自动配置原理

1.SpringBootApplication注解 springboot是基于spring的新型的轻量级框架,最厉害的地方当属**自动配置。**那我们就可以根据启动流程和相关原理来看看,如何实现传奇的自动配置 SpringBootApplication//标注在某个类上,表示这个类是SpringBo…

<蓝桥杯软件赛>零基础备赛20周--第15周--快速幂+素数

报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周。 在QQ群上交流答疑&am…

【设计模式】张一鸣笔记:责任链接模式怎么用?

我将通过一个贴近现实的故事——请假审批流程,带你了解和掌握责任链模式。 什么是责任链模式? 责任链模式是一种行为设计模式,它让你可以避免将请求的发送者与接收者耦合在一起,让多个对象都有处理请求的机会将这个对象连成一条…

同样是IT行业,测试和开发薪资真就差这么大吗?

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

前端学习笔记 7:小兔鲜

前端学习笔记 7:小兔鲜 准备工作 创建项目 创建项目: npm init vuelatest相关选项如下: 在src目录下添加以下目录: 别名路径联想 默认情况下在 VSCode 中输入import xxx from ...时不会启用路径联想功能,要启用需…

使用宝塔面板安装wiki.js详细教程

因为在安装过程中遇到了一些问题,花费了很长时间在解决问题上。根据这篇教程可以少踩很多坑。点赞加关注吧。 准备运行环境 Nodejs 在宝塔面板的软件商店中找到nodejs版本管理器并安装。 点击设置,选择一个稳定版安装。 PostgreSQL 官方推荐的数据库是…

用户洞察:精准解读用户的真实需求!

洞察用户需求的过程和谈恋爱一样。你不能简简单单地问客户,你想要什么?你有什么痛点?这样的问法是无法得到任何有价值的信息。这就好比谈恋爱的场景,如果你问对方想吃什么,大概率会得到“随便”“都行”这类的答案&…

力扣62. 不同路径

动态规划 思路: 定义 dp[r][c] 为到达坐标 (r, c) 的路径数: 它只能有同一行左边相邻方格向右到达或者同一列上方相邻方格向下到达;状态转移方程: dp[r][c] dp[r][c - 1] dp[r - 1][c]初始状态 dp[0][0] 1第一行的路径数是 1第…