【JVM】——JVM运行机制、类加载机制、内存划分

阿华代码,不是逆风,就是我疯

你们的点赞收藏是我前进最大的动力!!

希望本文内容能够帮助到你!!

目录

一:JVM引入

1:编程语言

2:JAVA运行机制

二:JVM中内存区域划分

1:堆

2:栈

(1)本地方法栈

(2)虚拟机栈

3:程序计数器

4:元数据区

[三:JVM的类加载机制(重点 )](#三:JVM的类加载机制(重点 ))

1:类加载

2:类加载过程

(1)加载

(2)验证

(3)准备

(4)解析

(5)初始化

3:双亲委派模型

(1)类加载器

(2)模型工作过程


一:JVM引入

IDEA运行代码离不开三个东西

①JVM------Java虚拟机

②JRE------Java运行时环境

③JDK------Java开发工具包

③包含②,②包含①

1:编程语言

在计算机导论中,我们把编程语言可以分为:编译型语言和解释型语言(虽然现在不适用了)

**编译型语言:**将像JAVA或者C++这样的高级语言,转化为二进制的机器指令,最后由CPU进行执行

**解释型语言:**边转化二进制机器指令,CPU边执行

2:JAVA运行机制

Java属于"半编译,边解释",目的是为了**跨平台。**我们知道不同的cpu,上面支持的指令格式并不一样。JAVA想要达到编译一遍,就能在多种CPU上执行。这里的过程简述如下

①通过javac把.java文件转化为.class文件

(.class文件就是字节码文件,包含的就是java字节码,可以理解成java自己搞的一套"CPU指令")

②这个.class文件在某个具体的操纵系统上执行,此时JVM就会把.class文件转化为当前cpu能识别的机器指令。

(JVM相当于翻译官)

总结:我们编写和发布一个Java程序,只需发布一个.class文件就可以了,剩下的交给JVM(爹~!)

二:JVM中内存区域划分

JVM本身就是一个进程,在运行过程中就会向操作系统这里申请一些资源(内存),比如在Java中定义变量,就是jvm去申请内存空间

1:堆

代码中new出来的对象 就是在堆里面;对象中持有的非静态成员变量也就是在堆里

2:栈

包含了方法的调用关系和局部变量

(1)本地方法栈

本地也就是jvm内部 ,通过c++写的代码中的一些调和关系和局部变量(关注较少)

(2)虚拟机栈

记录Java代码中(IDEA中)的调用关系和局部变量(一般说栈默认指虚拟机栈)

注:这里说的栈,和数据结构中的栈不是一回事

3:程序计数器

这个区域空间比较小,用来存储下一条要执行的java指令地址

4:元数据区

java1.8以前也叫"方法区"。我们写的代码,由javac转化为字节码,再由jvm把字节码加载到内存中放到元数据区(方法区)中,程序就按照元数据中记录的字节码依次执行

"元数据" (meta data)计算机术语,指的是一些辅助性性质的,描述性质的属性

例如:类的信息,方法的信息,一个程序有哪些类,类里有哪些方法,方法中包含哪些指令

例如:文件大小、位置、拥有者、修改时间、

三:JVM的类加载机制(重点 )

1:类加载

指java进程运行时,把.class文件从硬盘读取到内存,并进行校验解析的过程

2:类加载过程

Java官方文档中有详细说明Java SE Specifications

(1)加载

找到硬盘上的.class文件,打开文件,读取文件内容(二进制数据)

(2)验证

确保读取到的数据内容是合法的.class文件(字节码文件)

①类型

c++中没有规定类型有多长,而是规定这个类型不能短于多长,所以程序员用typedef自己定义出一些类型,u4,u2就是在描述这个类型的长度

②magic

majic也叫做magic number 魔幻数字,广泛应用于二进制文件格式中,用来标识当前二进制文件的格式是哪种类型

③JVM内部的版本,高版本的JVM可以运行低版本的.class文件,反之不一定可以

④常量池

⑤针对类的修饰限定符只有public和default两种

⑥当前类的其它信息和父类息

⑦每一个元素就是一个field_info,描述每一个成员,属性的相关信息(属性的名字、类型,访问权限,)

⑧方法信息

⑨注解

(3)准备

给类对象申请内存空间,此时申请到的内存空间,里面的默认值都是0

(4)解析

针对字符串常量进行处理------JVM将常量池中的符号引用替换为直接引用的过程,也就是初始化常量的过程

等.class文件被JVM加载到内存当中后,此时"hello"就有真实的地址了

(5)初始化

针对对象完成后续的初始化

3:双亲委派模型

双亲委派模型是处于加载环节中的,它描述的是如何查找.class文件

彩蛋:起"双亲"为名字,纯是为了好听,其实单亲更符合实际

(1)类加载器

在JVM中有一个专们进行类加载的模块------"类加载器"(ClassLoader)

默认的类加载器有三个:

①BootstrapClassLoader------负责查找标准库的目录

注:Java语法规范中描述了标准库中应该有哪些功能,像我们熟知的java.lang,java.util等就是标准库中的核心组件

②ExtensionClassLoader------负责查找扩展库的目录

注:实现JVM的厂商/组织,会在标准库的基础上在扩展实现一些功能,这些功能就放在扩展库里

③ApplicationClassLoader------负责查找当前项目的代码目录和第三方库目录

注:上述三个类加载器,存在像二叉树里那种"父子关系",有一个指针引用指向自己的"父亲"类加载器

(2)模型工作过程

①将ApplicationClassLoader作为入口进入,ApplicationClassLoader不会选择立刻在自己的目录开始搜寻,而是把任务交给自己的parent

②ExtensionClassLoader收到任务后,不会立刻搜索自己的目录,而是传给parent

③BootstrapClassLoader同样把任务甩给parent,但是发现parent是null,没有"父亲"

④所以只能自己搜寻了------尝试在标准库中搜寻符合要求的.class文件。如果找到了,就步入下一个验证环节;如果没找到就把任务返还孩子

⑤ExtensionClassLoader收到搜寻任务后同样再扩展目录中开始搜寻,如果找到了,就步入下一个验证环节;如果没找到就把任务返还孩子

⑥ApplicationClassLoader收到任务在当前项目代码目录和第三方库目录中找,如果找到了,就步入下一个验证环节;如果没找到就表示类加载失败抛出"ClassNotFoundException"异常

注:上述的规则,是JVM自带的类加载器默认遵循的规则。我们也可以自己写一个类加载器,打破上述规则(铁批表示规则就是用来打破的~~~)

相关推荐
极客先躯1 个月前
高级java每日一道面试题-2024年10月9日-JVM篇-什么是双亲委派模型?
java·双亲委派模型·jvm篇·启动类加载器·扩展类加载器·应用程序类加载器·自定义类加载器
螺蛳粉只吃炸蛋的走风2 个月前
面试题总结(三) -- 内存管理篇
c语言·c++·面试·内存·堆栈·raii
码农NoError3 个月前
数据结构特点
数据结构·链表·数组·队列·堆栈
shadow3D5 个月前
MDK-ARM 编译后 MAP 文件分析
stm32·嵌入式·map·堆栈
橘色的喵5 个月前
使用`LD_PRELOAD`和`jemalloc`实现C/C++信号的内存堆栈信息收集
信号·堆栈·ld_preload·preload·sigusr1·jemalloc·堆栈打印
胡斌附体7 个月前
软考之零碎片段记录(二十七)+复习巩固(十三、十四)
软考·硬件·程序计数器·案例题·risc和cisc·指令寄存器·贮存和状态条件寄存器
一支春夏、几多秋冬9 个月前
Linux程序崩溃调试
linux·堆栈
道长道长IOT9 个月前
浅析前端的堆栈原理以及深浅拷贝原理
前端·javascript·堆栈·深浅拷贝
baiyu339 个月前
cpptrace 库介绍
调试·cpp·exception·堆栈·cpptrace