前言

JVM一直是java知识里面进阶阶段的重要部分,如果希望在java领域研究的更深入,则JVM则是如论如何也避开不了的话题,本系列试图通过简洁易读的方式,讲解JVM必要的知识点。

运行流程

我们都知道java一直宣传的口号是:一次编译,到处运行。那么它如何实现的呢?我们看下图:

java程序经过一次编译之后,将java代码编译为字节码也就是class文件,然后在不同的操作系统上依靠不同的java虚拟机进行解释,最后再转换为不同平台的机器码,最终得到执行。这样我们是不是可以推演,如果要在mac系统上运行,是不是只需要安装mac java虚拟机就行了。那么了解了这个基本原理后,我们尝试去做更深的研究,一个普通的java程序它的执行流程到底是怎样的呢?例如我们写了一段这样的代码:

public class HelloWorld { public static void main(String[] args) { System.out.print("Hello world"); } }

这段程序从编译到运行,最终打印出“Hello world”中间经过了哪些步骤呢?我们直接上图:

java代码通过编译之后生成字节码文件(class文件),通过:java HelloWorld执行,此时java根据系统版本找到jvm.cfg,各位可以搜索一下自己电脑上的jvm.cfg文件在哪,它会根据你的系统版本放在不同的位置,比如我的这个文件就在:C:\Program Files\Java\jdk1.8.0_101\jre\lib\amd64\jvm.cfg,打开看一下:

这是我电脑上的文件,其中-server KNOWN就表示名称为server的jvm可用。如果这时你搜索一下你电脑上jvm.dll,你就会发现它一定在你的某个server目录下,比如我的:C:\Program Files\Java\jdk1.8.0_101\jre\bin\server\jvm.dll。简而言之就是通过jvm.cfg文件找到对应的jvm.dll,jvm.dll则是java虚拟机的主要实现。接下来会初始化JVM,并且获取JNI接口,什么是JNI接口,就是java本地接口,你想啊java被编译成了class文件,JVM怎么从硬盘上找到这个文件并装载到JVM里呢,就是通过JNI接口(它还常用于java与操作系统、硬件交互),找到class文件后并装载进JVM,然后找到main方法,最后执行。

JVM基本结构

可能通过上面的描述,大家对JVM运行流程有了一个粗略的认识,那么JVM内部到底是怎么执行一个class文件的呢,也就是上图中最后一步第6步的内部细节是怎样的呢?要了解这个问题,我们首先得看一下JVM的内部结构:

从这个结构不难看出,class文件被jvm装载以后,经过jvm的内存空间调配,最终是由执行引擎完成class文件的执行。当然这个过程还有其他角色模块的协助,这些模块协同配合才能让一个java程序成功的运行,下面就详细介绍这些模板,它们也是后面学习jvm最重要的部分。

内存空间:

JVM内存空间包含:方法区、java堆、java栈、本地方法栈。

方法区是各个线程共享的区域,存放类信息、常量、静态变量。

java堆也是线程共享的区域,我们的类的实例就放在这个区域,可以想象你的一个系统会产生很多实例,因此java堆的空间也是最大的。如果java堆空间不足了,程序会抛出OutOfMemoryError异常。

java栈是每个线程私有的区域,它的生命周期与线程相同,一个线程对应一个java栈,每执行一个方法就会往栈中压入一个元素,这个元素叫“栈帧”,而栈帧中包括了方法中的局部变量、用于存放中间状态值的操作栈,这里面有很多细节,我们以后再讲。如果java栈空间不足了,程序会抛出StackOverflowError异常,想一想什么情况下会容易产生这个错误,对,递归,递归如果深度很深,就会执行大量的方法,方法越多java栈的占用空间越大。

本地方法栈角色和java栈类似,只不过它是用来表示执行本地方法的,本地方法栈存放的方法调用本地方法接口,最终调用本地方法库,实现与操作系统、硬件交互的目的。

PC寄存器,说到这里我们的类已经加载了,实例对象、方法、静态变量都去了自己改去的地方,那么问题来了,程序该怎么执行,哪个方法先执行,哪个方法后执行,这些指令执行的顺序就是PC寄存器在管,它的作用就是控制程序指令的执行顺序。

执行引擎当然就是根据PC寄存器调配的指令顺序,依次执行程序指令。

结语

本文主要介绍了java虚拟机运行的基本流程,以及java虚拟机内部结构。下一篇我们将学习java内存模型以及探索java变量的可见性、有序性、指令重排等问题。

JVM学习--(一)基本原理的更多相关文章

  1. 【转载】JVM 学习——垃圾收集器与内存分配策略

    本文主要是对<深入理解java虚拟机 第二版>第三章部分做的总结,文章中大部分内容都来自这章内容,也是博客 JVM 学习的第二部分. 简述 说到垃圾收集(Garbage Collectio ...

  2. JVM学习笔记——内存结构篇

    JVM学习笔记--内存结构篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存结构部分 我们会分为以下几部分进行介绍: JVM整体介绍 程序计数器 虚拟机栈 本地方法栈 堆 方法 ...

  3. JVM学习(4)——全面总结Java的GC算法和回收机制

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 一些JVM的跟踪参数的设置 Java堆的分配参数 -Xmx 和 –Xms 应该保持一个什么关系,可以让系统的 ...

  4. JVM学习(3)——总结Java内存模型

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...

  5. Java虚拟机JVM学习07 类的卸载机制

    Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...

  6. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  7. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  8. Java虚拟机JVM学习04 类的初始化

    Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...

  9. Java虚拟机JVM学习03 连接过程:验证、准备、解析

    Java虚拟机JVM学习03 连接过程:验证.准备.解析 类被加载后,就进入连接阶段. 连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去. 连接阶段三个步骤:验证.准备和解析. 类 ...

随机推荐

  1. (NO.00004)iOS实现打砖块游戏(十):砖块!更多的砖块!

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 到目前为止游戏基本可玩,但是砖块数量是不变的,等玩家打光所有的砖 ...

  2. eclipse new server Cannot create a server using the selected type 网上有两种办法,其实原理一样

    eclipse new server Cannot create a server using the selected type 网上有两种办法,其实原理一样 第一种说法: 还真的找到解决的方法了, ...

  3. HMM:隐马尔科夫模型-维特比算法

    http://blog.csdn.net/pipisorry/article/details/50731584 目标-解决HMM的基本问题之二:给定观察序列O=O1,O2,-OT以及模型λ,如何选择一 ...

  4. Struts2进阶(一)运行原理及搭建步骤

    Struts2进阶(一)运行原理 Struts2框架 Struts2框架搭建步骤 致力于web服务,不可避免的涉及到编程实现部分功能.考虑使用到SSH框架中的Struts2.本篇文章只为深入理解Str ...

  5. pig的内置函数小总结(不全)

    piggybank里面有很多函数,可以用register和define调用.也可以用java仿照piggybank自行开发. 比如读sequence二进制文件,可以用piggybank里面函数Sequ ...

  6. 《java入门第一季》之tcp协议下的网络编程c/s实现通信交互

    需求:客户端向服务器发送数据,服务器端收到数据后向客户端返回数据: 还是使用两台电脑,一台客户端,一台服务器. 客户端代码: import java.io.IOException; import ja ...

  7. bootmgr解压缩

    主要参考以下两个文章: 1.  http://bbs.wuyou.com/forum.php?mod=viewthread&tid=211314 2.  http://reboot.pro/f ...

  8. C算法分解质因数与分解因子

    ) ) printf("%d ",i); } }

  9. UNIX环境高级编程——文件和目录

    一.获取文件/目录的属性信息 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); in ...

  10. XML Publisher Report Issues, Recommendations and Errors

    In this Document   Purpose   Questions and Answers   References APPLIES TO: Oracle Process Manufactu ...