JVM概述和类加载子系统

简介: 我记得当年学java的时候,就很好奇,为什么我在IDEA上写一些代码(其实就是一堆我们人能知道的英文单词的组合加一些运算符),为什么就可以在windows上运行后执行我们的指令,而且还可以打成jar包去linux系统跑起来,为什么一份代码可以在不同平台运行呢?类是如何加载的?对象如何创建的以及都有哪些信息?我创建的对象被分配到哪个内存去了?java是怎么和我们操作系统打交道的又是怎么调用CPU为我们计算的?创建了对象分配了内存,为什么可以不用手动回收就可以自动清理内存等等等,相信你也同样有过这些困惑。

目录

一、前言

大家好,我是苍何。最近思考了一个问题,为什么会出现公司面试造火箭,工作扭螺丝的现象,包括各种八股文的连环大绝杀问到你不会为主,其实这是考察你的知识面以及掌握的深度,而为什么需要这样呢?归其原因,无非是通过筛选找到那些会思考的人,他们需要的并不是CRUD的工具人,而是会思考能创新的工程师。

当你深刻理解到这点,我想不用刻意去学习,在工作中,肯定会吾日三省吾身。

于是乎,这个重新开始学习编程系列文章出来了。

愿与君共勉!

我记得当年学java的时候,就很好奇,为什么我在IDEA上写一些代码(其实就是一堆我们人能知道的英文单词的组合加一些运算符),为什么就可以在windows上运行后执行我们的指令,而且还可以打成jar包去linux系统跑起来,为什么一份代码可以在不同平台运行呢?类是如何加载的?对象如何创建的以及都有哪些信息?我创建的对象被分配到哪个内存去了?java是怎么和我们操作系统打交道的又是怎么调用CPU为我们计算的?创建了对象分配了内存,为什么可以不用手动回收就可以自动清理内存等等等,相信你也同样有过这些困惑。

之前我都是部分在一些博客或者网站上进行查看资料,概念大概能理解,但可能还不够系统的掌握这部分知识,现在我看了几百集的宋红康老师的视频教程,感到收益匪浅,特此总结记录一下。

下面就我的理解以及一些宋红康老师的图形进行一个系统的总结。我做了个系统轮廓的导图:

为了防止文章过于长,我将分几篇文章进行发布。

二、虚拟机的概念

系统虚拟机:
VMware,可运行完整操作系统的软件平台
程序虚拟机:
运行字节码指令,如java虚拟机

三、JVM整体概述

执行字节码的虚拟计算机,所有java程序都运行在java虚拟机内部
一次编译,到处运行,自动内存管理,自动垃圾回收功能

1、JVM整体架构


2、java代码的执行流程

java程序经过前端编译器编译成class文件,也即字节码文件,这些文件我们用文本工具打开,就是这样一串乱码的东东


我们可以用idea的jclasslib Bytecodes viewver打开字节码文件,可以看到其实是包含很多结构的,有方法的信息,字节码指令,局部变量表信息及长度等。

表明这个class文件其实就是一些指定格式的文件,也就是说不光java语言,其他语言,只要按照规范的格式也是可以被JVM虚拟机识别并执行的,所以JVM不仅仅只是java虚拟机。

如下图,不同平台的JVM实现会去运行字节码文件,通过JVM转为各个系统所能识别的操作指令,然后通过CPU执行运算,这就是java代码的执行流程,当然这其中会涉及很多,让我们慢慢看。


3、JVM生命周期

1、虚拟机的启动
是通过引导类加载器创建一个初始类来完成的,这个类是由虚拟机的具体实现指定的
2、虚拟机的执行
程序开始执行,程序结束后就结束,
执行一个所谓的java程序,真正在执行的是一个叫java虚拟机的进程
3、虚拟机的退出
程序正常结束、异常、操作系统出现错误,线程调用System.exit()方法

4、JVM发展历程

1、Sun Classic VM
第一款商用虚拟机,只提供了解释器,现在hotspot内置了此虚拟机
2、exact VM
准确是内存管理
3、HotSpot VM
通过计数器找到最具编译价值代码,触发即时编译或栈上替换
通过边以及与解释器协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡
4、JRockit
专注于服务器端应用数据显示是最快的虚拟机,全部代码都靠即时编译器执行
5、J9
有影响力的三大商用虚拟机之一,

四、类加载子系统

1、概述

类加载子系统是JVM用类加载器将类加载进内存,类的信息会存放于运行时数据区的方法区(后面会细说),加载类的时候也会做一些初始化的操作,如会进行clinit和init等。

2、类的加载过程

相信很多伙伴面试都被问到过这吧,要说好这道题,得仔细理解。

总共分三大快来讲
首先是加载阶段,将.class文件加载到内存
其次是链接阶段,这部分又包含验证、准备和解析阶段
最后最初始化操作

加载阶段:


链接阶段

初始化

clinit其实就是初始化类中静态的变量,如int静态变量会初始化为0,init就是初始化类的构造器。

3、类加载器

分2类,引导类加载器和自定义类加载器,直接或间接继承抽象类ClassLoader的类加载器都划分为自定义类加载器。

这里说几个常用的类加载器,在后面双亲委派机制会用到
1、启动类加载器(Bootstrap ClassLoader)
虚拟机自带的加载器,java的核心类库都是通过该类加载器进行加载的,处于安全,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类
2、扩展类加载器
加载扩展目录jre/lib/ext子目录下的
3、系统类加载器
用户自定义的类来说,默认用的是系统类加载器进行加载(属于自定义类加载器)

注意:这三个是有层级关系的,123分别是从上到下的关系,这里的层级并不是父子的关系,倒像是目录的那种层级关系

如何获取当前类的类加载器:

4、双亲委派机制

一个类加载器收到了类加载请求,他是不会先去自己加载的,而是会去委托自己的父类去加载,如果父类加载器还存在其父类加载器,则递归一直向上委托,请求其实最终都会到达顶层的启动类加载器(这里不明白层级的可以看第3点讲的层级关系),如果父类加载器可以加载该类就由他来加载,如果做不到,就给子类自己去加载罢了。



优势:
1、避免类重复加载
2、保护程序安全,防止核心类API被篡改。

5、沙箱安全机制

所谓沙箱安全机制,其实就是为了保护java的核心API而设置的,其实和双亲委派机制都是用来保护核心API的,比如,你自定义一个包也叫java.lang,并也定义了一个类也叫String,这时候定义一个main方法,启动,会发现程序报错。

这是因为,类加载器真正去加载的其实是核心API下的String类,根本不是我们自定义的类,也就是我们自定义的类压根没被加载到内存中来,当我们执行main方法,核心包下的String类当然没有该方法。

所以在建包的时候,也不允许建和核心API同名的包,实际公司中,通常都会以公司域名或者标识进行包名命名。

目录
相关文章
|
2月前
|
缓存 前端开发 Java
JVM知识体系学习二:ClassLoader 类加载器、类加载器层次、类过载过程之双亲委派机制、类加载范围、自定义类加载器、编译器、懒加载模式、打破双亲委派机制
这篇文章详细介绍了JVM中ClassLoader的工作原理,包括类加载器的层次结构、双亲委派机制、类加载过程、自定义类加载器的实现,以及如何打破双亲委派机制来实现热部署等功能。
77 3
|
3月前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
133 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
4月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
34 3
|
4月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
246 0
|
5月前
|
存储 缓存 自然语言处理
(三)JVM成神路之全面详解执行引擎子系统、JIT即时编译原理与分派实现
执行引擎子系统是JVM的重要组成部分之一,在JVM系列的开篇曾提到:JVM是一个架构在平台上的平台,虚拟机是一个相似于“物理机”的概念,与物理机一样,都具备代码执行的能力。
104 1
|
5月前
|
存储 前端开发 Java
(二)JVM成神路之剖析Java类加载子系统、双亲委派机制及线程上下文类加载器
上篇《初识Java虚拟机》文章中曾提及到:我们所编写的Java代码经过编译之后,会生成对应的class字节码文件,而在程序启动时会通过类加载子系统将这些字节码文件先装载进内存,然后再交由执行引擎执行。本文中则会对Java虚拟机的类加载机制以及执行引擎进行全面分析。
103 0
|
5月前
|
Java Perl
JVM内存问题之如何统计在JVM的类加载中,每一个类的实例数量,并按照数量降序排列
JVM内存问题之如何统计在JVM的类加载中,每一个类的实例数量,并按照数量降序排列
|
5月前
|
存储 安全 Java
开发与运维引用问题之JVM类加载过程如何解决
开发与运维引用问题之JVM类加载过程如何解决
37 0
|
5月前
|
存储 算法 Java
JAVA程序运行问题之Java类加载到JVM中加载类时,实际上加载的是什么如何解决
JAVA程序运行问题之Java类加载到JVM中加载类时,实际上加载的是什么如何解决
|
6月前
|
安全 前端开发 Java
《JVM由浅入深学习【一】 》JVM由简入深学习提升(类加载过程+父子类加载过程+类加载器+双亲委派机制)
《JVM由浅入深学习【一】 》JVM由简入深学习提升(类加载过程+父子类加载过程+类加载器+双亲委派机制)
48 0