JVM虚拟机学习总结(一)

1.JVM类加载器原理

JVM的工作流程是.java文件通过javac编译成.class文件,然后利用类加载器将字节码文件加载到内存中,然后通过解释器来编译成机器代码,然后执行。

每一个类加载器都有同一个最终的父类BootStrapClassLoader,在类加载器检查类是否已存在在加载器的类库中时,类加载器的执行顺序为:

CustomClassLoader(用户自定义的类加载器)

                         ↓

AppClassLoader(系统类加载器)

                         ↓

EcxtensionClassLoader(扩展类加载器)

                         ↓

BootStrapClassLoader(最顶层加载器)

在加载器执行的过程中如果CustomClassLoader加载器在自己的库中找不到对应的类文件,就会委托给AppClassLoader继续查找,同理如果AppClassLoader在自己的库中也找不到对应的类文件就会继续委托它的上一层EcxtensionClassLoader类加载器去查找,以此类推最终如果BootStrapClassLoader加载器也找不到对应的类文件,就会尝试去加载这个类。

尝试加载类的顺序为:

LoadJRE\lib\rt.jar或者-xbootClassPath指定的jar包(由BootStrapClassLoader加载器加载)

                         ↓

LoadJRE\lib\ertr\*.jar或者-Djava.ert.dirs指定目录下的jar包(由EcxtensionClassLoader加载器加载)

                         ↓

loadCLASSPATH或者-Djava.class.path所指定目录下的jar包(由AppClassLoader加载器加载)

                         ↓

通过java.lang.ClassLoader的自定义加载器加载class(由CustomClassLoader加载器加载)。

  • 在JVM中累的完整标识:ClassLoader+package+className;
  • 类加载器的可见性限制:下层的加载器能够看到上层加载器中的类,反之则不被允许,也就是说委托只能从下到上;
  • 不可卸载类:类加载器可以加载一个类,但是它不能卸载一个类,但是类加载器可以被删除以及被创建;

JVM的接下来的执行流程为:

loading(加载类)

                            ↓

verifying(验证java以及JVM规范)

                            ↓

preparing(为类分配内存,确定类的属性、方法以及数据结构)

                            ↓

resolving(将该类常量池中的符号引用改为直接引用)

                            ↓

initialing(初始化类的局部变量,为静态域赋值,同时执行静态初始化块)

2.JVM的运行数据区域

运行数据区域主要包含六个模块,六个模块又分别属于每个线程独立拥有的以及所有线程共有的模块

每个线程独立拥有的如下:

  1. java栈
  2. 程序代数寄存器(PC寄存器)
  3. 本地方法栈

所有线程共有的如下:

  1. java堆
  2. 方法区域
  3. 运行常量池
  • Java栈:java栈是每个线程单独拥有的,线程启动时创建,java栈中存放着一系列的栈帧,JVM只能进行压入(push)和弹出(Pop)栈帧这两种操作,每调用一个方法JVM就向Java栈中压入一个栈帧,方法结束返回时弹出栈帧,如果方法执行时出现异常可以调用printStackTrace方法查看栈的情况。
  • PC计数器:每个线程都有一个PC计数器,当线程启动时PC计数器被创建,这个计数器存放当前正在被执行的字节码指令。
  • 本地方法栈:程序通过JNI(注释1)调用本地代码,就根据本地方法语言类型建立相同的栈。
  • Java堆:Java堆中存放的是程序创建的对象或者实例,这个区域对JVM的性能影响很大,垃圾回收机制处理正是指的这一块区域。
  • 方法区域:方法区域是JVM中所有线程共享的,当启动一个JVM实例时方法区域被创建用来存放常量池、有关域和方法的信息,静态变量、类和方法的字节码。
  • 运行常量池:存放类和接口的常量除此之外还存放方法和域所有的引用,当一个方法或域被引用时JVM就通过运行常量池中的这些引用来查找它们的实际地址。

 

注释1:JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境。

借鉴:http://blog.csdn.net/bingduanlbd/article/details/8363734

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值