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

简介: JVM运行机制,堆栈,程序计数器,元数据区,JVM加载机制,双亲委派模型

  image.gif 编辑

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

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

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

目录

一:JVM引入

1:编程语言

2:JAVA运行机制

二:JVM中内存区域划分

1:堆

2:栈

(1)本地方法栈

(2)虚拟机栈

3:程序计数器

4:元数据区

三: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(爹~!)

image.gif 编辑

二:JVM中内存区域划分

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

image.gif 编辑

1:堆

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

2:栈

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

(1)本地方法栈

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

(2)虚拟机栈

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

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

3:程序计数器

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

4:元数据区

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

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

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

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

image.gif 编辑

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

1:类加载

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

2:类加载过程

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

image.gif 编辑

image.gif 编辑

(1)加载

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

(2)验证

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

image.gif 编辑

①类型

image.gif 编辑

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

②magic

image.gif 编辑

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

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

image.gif 编辑

④常量池 image.gif 编辑

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

image.gif 编辑

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

image.gif 编辑

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

image.gif 编辑

⑧方法信息

image.gif 编辑

⑨注解

image.gif 编辑

(3)准备

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

(4)解析

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

image.gif 编辑

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

(5)初始化

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

3:双亲委派模型

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

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

(1)类加载器

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

默认的类加载器有三个:

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

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

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

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

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

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

(2)模型工作过程

image.gif 编辑

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

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

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

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

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

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

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

相关文章
|
6月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
631 55
|
1月前
|
存储 缓存 Java
我们来说一说 JVM 的内存模型
我是小假 期待与你的下一次相遇 ~
209 4
|
1月前
|
存储 缓存 算法
深入理解JVM《JVM内存区域详解 - 世界的基石》
Java代码从编译到执行需经javac编译为.class字节码,再由JVM加载运行。JVM内存分为线程私有(程序计数器、虚拟机栈、本地方法栈)和线程共享(堆、方法区)区域,其中堆是GC主战场,方法区在JDK 8+演变为使用本地内存的元空间,直接内存则用于提升NIO性能,但可能引发OOM。
|
7月前
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
615 6
|
12月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
2010 1
|
10月前
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
1032 166
|
8月前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
391 29
JVM简介—1.Java内存区域
|
8月前
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
|
8月前
|
存储 设计模式 监控
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
240 0
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
|
9月前
|
存储 算法 Java
JVM: 内存、类与垃圾
分代收集算法将内存分为新生代和老年代,分别使用不同的垃圾回收算法。新生代对象使用复制算法,老年代对象使用标记-清除或标记-整理算法。
141 6