欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JVM学习笔记(一)——内存模型,类加载过程

程序员文章站 2024-01-10 19:54:52
JVM整体架构字节码文件编译到Class loader system。其中方法区和堆(黄颜色)是线程共享的,其他三个是每个线程独有一份的。Java代码执行过程因为操作系统不识别高级语言,只识别机器指令,所以需要从高级语言=》汇编语言=》机器指令。Java文件从编译器到字节码文件,字节码文件从类加载器到校验器最后到编译执行。JIT编译器可以将多次执行的热点代码缓存起来,下次可以直接使用,提高了效率。JVM的生命周期JVM发展历程Sun Classic VM:世界上第一款商用Java虚...

JVM整体架构

JVM学习笔记(一)——内存模型,类加载过程

字节码文件编译到Class loader system。
其中方法区和堆(黄颜色)是线程共享的,其他三个是每个线程独有一份的。

Java代码执行过程

因为操作系统不识别高级语言,只识别机器指令,所以需要从高级语言=》汇编语言=》机器指令。
Java文件从编译器到字节码文件,字节码文件从类加载器到校验器最后到编译执行。
JIT编译器可以将多次执行的热点代码缓存起来,下次可以直接使用,提高了效率。

JVM学习笔记(一)——内存模型,类加载过程

JVM的生命周期

JVM学习笔记(一)——内存模型,类加载过程
JVM学习笔记(一)——内存模型,类加载过程

JVM发展历程

Sun Classic VM:世界上第一款商用Java虚拟机。
这款虚拟机内部只提供解释器。

Exact VM

Hot Spot:现在的jdk都是基于该虚拟机。
BEA的JRockit:这款虚拟机内部没有解释器,就通过即时编译器。是世界上最快的JVM。
IBM的J9
Apache的Harmony

JVM学习笔记(一)——内存模型,类加载过程
解释器和JIT即时编译器,可以不是同时存在的。
早期的java虚拟机就只有解释器,但是这样就会导致效率很低下,比如循环里一段重复的代码要重复,所以加上JIT即时编译器,就会将一些热点代码缓存起来,配合使用,效率更快。

类加载器子系统

class load system:加载字节码文件,分为三大步骤。
1、加载阶段。
2、链接阶段。
3、初始化阶段。

JVM学习笔记(一)——内存模型,类加载过程

类的加载过程

JVM学习笔记(一)——内存模型,类加载过程

1、加载

JVM学习笔记(一)——内存模型,类加载过程

2、链接

JVM学习笔记(一)——内存模型,类加载过程

JVM学习笔记(一)——内存模型,类加载过程

变量在prepare只是生成默认的初始值,在后面的inital初始化才会给它赋值。
常量,final修饰的,在prepare就会进行初始化。

3、初始化

JVM学习笔记(一)——内存模型,类加载过程

JVM学习笔记(一)——内存模型,类加载过程

JVM学习笔记(一)——内存模型,类加载过程

< clinit >() 就是类里静态赋值的过程。如上图。
上述先linking中的prepare将各个变量做初始化操作。
再由< clinit >() 方法自上而下做赋值操作。
变量num: 先给1,在给2.
变量number: 先给20,在给10.
所以,当定义在static下面时,此时打印出的是下面的值。

< init >() 是指构造函数里的赋值过程。
java每个类都必须有构造函数,所以肯定也会有< init >() 方法。
但,如果没有给static之类的类变量,则可以没有< clinit >() 。

如果存在继承关系
JVM学习笔记(一)——内存模型,类加载过程

如上图所示。main用到了son这个类,所以去引用它,引用之前发现son用到father,所以要先初始化father(加载,链接,初始化)一系列操作后,A=2,所以son去引用时,就是2这个值。可以看下面的字节码源码。

JVM学习笔记(一)——内存模型,类加载过程

一个类的< clinit >() 方法在多线程下会在被同步加锁
JVM学习笔记(一)——内存模型,类加载过程
上述可以看出,两个类在runnable里都要初始化这个类,一个线程进来后锁住了,另一个进不来,导致阻塞。

类加载器分类

引导类加载器:是由C/C++编写的,在java里获取不到,为null,主要加载java的核心类库。
扩展类加载器,系统类加载器:都是由java写的。可以通过getParent()获取。我们自己写的java类也是由该加载器进行加载。

JVM学习笔记(一)——内存模型,类加载过程

双亲委派机制

如果你创建一个包名叫java.lang的包,下面创建一个叫做String的类。这时候,你新建一个测试类去new这个String,会出现什么问题呢?会加载吗?

其实这时候会将委托抛给上层的父类,逐级往上,到引导类的时候,引导类刚好是加载核心java类下的(lang包归他管)所以他就加载系统String了。
如果父类没完成加载任务,子加载器才会自己去尝试加载。

JVM学习笔记(一)——内存模型,类加载过程

本文地址:https://blog.csdn.net/axiang_/article/details/107354666

相关标签: Java jvm