java class jvm_Java提升篇——JVM加载class文件的原理机制

在面试java工程师的时候,这道题常常被问到,故需特别注意。java

一、JVM 简介

JVM 是咱们Javaer 的最基本功底了,刚开始学Java 的时候,通常都是从“Hello World ”开始的,而后会写个复杂点class ,而后再找一些开源框架,好比Spring ,Hibernate 等等,再而后就开发企业级的应用,好比网站、企业内部应用、实时交易系统等等,直到某一天忽然发现作的系统咋就这么慢呢,并且时不时还来个内存溢出什么的,今天是交易系统报了StackOverflowError ,明天是网站系统报了个OutOfMemoryError ,这种错误又很难重现,只有分析Javacore 和dump 文件,运气好点还能分析出个结果,运行遭的点,就直接去庙里烧香吧!天天接客户的电话都是战战兢兢的,生怕再出什么幺蛾子了。我想Java 作的久一点的都有这样的经历,那这些问题的最终根结是在哪呢?—— JVM 。程序员

JVM 全称是Java Virtual Machine ,Java 虚拟机,也就是在计算机上再虚拟一个计算机,这和咱们使用 VMWare不同,那个虚拟的东西你是能够看到的,这个JVM 你是看不到的,它存在内存中。咱们知道计算机的基本构成是:运算器、控制器、存储器、输入和输出设备,那这个JVM 也是有这成套的元素,运算器是固然是交给硬件CPU 还处理了,只是为了适应“一次编译,随处运行”的状况,须要作一个翻译动做,因而就用了JVM 本身的命令集,这与汇编的命令集有点相似,每一种汇编命令集针对一个系列的CPU ,好比8086 系列的汇编也是能够用在8088 上的,可是就不能跑在8051 上,而JVM 的命令集则是能够处处运行的,由于JVM 作了翻译,根据不一样的CPU ,翻译成不一样的机器语言。面试

JVM 中咱们最须要深刻理解的就是它的存储部分,存储?硬盘?NO ,NO , JVM 是一个内存中的虚拟机,那它的存储就是内存了,咱们写的全部类、常量、变量、方法都在内存中,这决定着咱们程序运行的是否健壮、是否高效,接下来的部分就是重点介绍之。编程

二、JVM 的组成部分

咱们先把JVM 这个虚拟机画出来,以下图所示:安全

85a1a7ce746589a3fb9b2f641b2920d5.png

从这个图中能够看到,JVM 是运行在操做系统之上的,它与硬件没有直接的交互。咱们再来看下JVM 有哪些组成部分,以下图所示:框架

1ff9a84477047ba09db27d2da5a66406.png

该图参考了网上广为流传的JVM 构成图,你们看这个图,整个JVM 分为四部分:jvm

## Class Loader 类加载器编程语言

类加载器的做用是加载类文件到内存,好比编写一个HelloWord.java 程序,而后经过javac 编译成class 文件,那怎么才能加载到内存中被执行呢?Class Loader 承担的就是这个责任,那不可能随便创建一个.class 文件就能被加载的,Class Loader 加载的class 文件是有格式要求,在《JVM Specification 》中式这样定义Class 文件的结构:网站

ClassFile {

u4 magic;

u2 minor_version;

u2 major_version;

u2 constant_pool_count;

cp_info constant_pool[constant_pool_count-1];

u2 access_flags;

u2 this_class;

u2 super_class;

u2 interfaces_count;

u2 interfaces[interfaces_count];

u2 fields_count;

field_info fields[fields_count];

u2 methods_count;

method_info methods[methods_count];

u2 attributes_count;

attribute_info attributes[attributes_count];

}

须要详细了解的话,能够仔细阅读《JVM Specification 》的第四章“The class File Format ”,这里再也不详细说明。this

友情提示:Class Loader 只管加载,只要符合文件结构就加载,至于说能不能运行,则不是它负责的,那是由Execution Engine 负责的。

## Execution Engine 执行引擎

执行引擎也叫作解释器(Interpreter) ,负责解释命令,提交操做系统执行。

## Native Interface 本地接口

本地接口的做用是融合不一样的编程语言为Java 所用,它的初衷是融合C/C++ 程序,Java 诞生的时候是C/C++ 横行的时候,要想立足,必须有一个聪明的、睿智的调用C/C++ 程序,因而就在内存中专门开辟了一块区域处理标记为native 的代码,它的具体作法是Native Method Stack 中登记native 方法,在Execution Engine 执行时加载native libraies 。目前该方法使用的是愈来愈少了,除非是与硬件有关的应用,好比经过Java 程序驱动打印机,或者Java 系统管理生产设备,在企业级应用中已经比较少见,由于如今的异构领域间的通讯很发达,好比可使用Socket 通讯,也可使用Web Service 等等,很少作介绍。

## Runtime data area 运行数据区

运行数据区是整个JVM 的重点。咱们全部写的程序都被加载到这里,以后才开始运行,Java 生态系统如此的繁荣,得益于该区域的优良自治。

整个JVM 框架由加载器加载文件,而后执行器在内存中处理数据,须要与异构系统交互是能够经过本地接口进行,瞧,一个完整的系统诞生了!

三、JVM加载class文件的原理机制

Java中的全部类,都须要由类加载器装载到JVM中才能运行。类加载器自己也是一个类,而它的工做就是把class文件从硬盘读取到内存中。在写程序的时候,咱们几乎不须要关心类的加载,由于这些都是隐式装载的,除非咱们有特殊的用法,像是反射,就须要显式的加载所须要的类。

类装载方式,有两种

1.隐式装载, 程序在运行过程当中当碰到经过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中,

2.显式装载, 经过class.forname()等方法,显式加载须要的类

隐式加载与显式加载的区别:二者本质是同样?

Java类的加载是动态的,它并不会一次性将全部类所有加载后再运行,而是保证程序运行的基础类(像是基类)彻底加载到jvm中,至于其余类,则在须要的时候才加载。这固然就是为了节省内存开销。

Java的类加载器有三个,对应Java的三种类:(java中的类大体分为三种:   1.系统类   2.扩展类 3.由程序员自定义的类 )

Bootstrap Loader  // 负责加载系统类 (指的是内置类,像是String,对应于C#中的System类和C/C++标准库中的类)

|

- - ExtClassLoader   // 负责加载扩展类(就是继承类和实现类)

|

- - AppClassLoader   // 负责加载应用类(程序员自定义的类)

三个加载器各自完成本身的工做,但它们是如何协调工做呢?哪个类该由哪一个类加载器完成呢?为了解决这个问题,Java采用了委托模型机制。

委托模型机制的工做原理很简单:当类加载器须要加载类的时候,先请示其Parent(即上一层加载器)在其搜索路径载入,若是找不到,才在本身的搜索路径搜索该类。这样的顺序其实就是加载器层次上自顶而下的搜索,由于加载器必须保证基础类的加载。之因此是这种机制,还有一个安全上的考虑:若是某人将一个恶意的基础类加载到jvm,委托模型机制会搜索其父类加载器,显然是不可能找到的,天然就不会将该类加载进来。

咱们能够经过这样的代码来获取类加载器:

ClassLoader loader = ClassName.class.getClassLoader();

ClassLoader ParentLoader= loader.getParent();

注意一个很重要的问题,就是Java在逻辑上并不存在BootstrapKLoader的实体!由于它是用C++编写的,因此打印其内容将会获得null。

前面是对类加载器的简单介绍,它的原理机制很是简单,就是下面几个步骤:

1.装载:查找和导入class文件;

2.链接:

(1)检查:检查载入的class文件数据的正确性;

(2)准备:为类的静态变量分配存储空间;

(3)解析:将符号引用转换成直接引用(这一步是可选的)

3.初始化:初始化静态变量,静态代码块。

这样的过程在程序调用类的静态成员的时候开始执行,因此静态方法main()才会成为通常程序的入口方法。类的构造器也会引起该动做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值