首先我想从宏观上介绍一下Java虚拟机的工作原理。从最初的我们编写的Java源文件(.java文件)是如何一步步执行的,如下图所示,首先Java源文件经过前端编译器(javac或ECJ)将.java文件编译为Java字节码文件,然后JRE加载Java字节码文件,载入系统分配给JVM的内存区,然后执行引擎解释或编译类文件,再由即时编译器将字节码转化为机器码。主要介绍下图中的类加载器和运行时数据区两个部分。

JVM的整体架构

类加载子系统:

---负责从文件系统或者网络中加载class信息,存入方法区中。Java类的加载、连接和初始化都是在程序运行时完成的,只有在类被需要的时候才进行动态加载,更多的内容可以看类加载子系统的解析过程。Java的详解:JVM的类加载子系统的解析过程 – Break易站

方法区(Method Area):

存放加载后的class信息,包括静态方法,jdk1.6以前包含了常量池。更多的方法区在类加载的时候,究竟存储了什么呢?可以移步:Java虚拟机(JVM)的方法区(Method Area)存储了什么内容? – Break易站

参数:-XX:PermSize初始值  -XX:MaxPermSize最大值

Java堆(Heap):

Java工程的主要内存工作区域,所有线程共享,jdk1.7以后包含了常量池。参数: -Xms初始值     -Xmx最大值

直接内存:java堆外,直接向系统申请的内存区间,允许NIO库使用。申请空间慢,读写快。默认下最大可用空间等于堆的最大可用空间。在server模式下,读写速度是堆的10倍。

参数:-XX:MaxDirectMemorySize 最大值

垃圾回收器:

Java栈:线程私有,用于存放局部变量,方法参数,同时和java方法的调用返回密切相关。

参数:-Xss最大值

本地方法栈:和java栈类似,主要用于本地方法调用。

PC寄存器:线程私有

执行引擎:

Java [-options] class [args...]

其中-options是java虚拟机的启动参数,args是传递给main方法的参数、

从Java平台的逻辑结构上来看,我们可以从下图来了解JVM:

从上图能清晰看到Java平台包含的各个逻辑模块,也能了解到JDK与JRE的区别,对于JVM自身的物理结构,我们可以从下图鸟瞰一下:

JVM的运行如下图:

从图中,可知内存分为线程私有和共享两大类:

(1)线程私有区,包含以下3类:

程序计数器,记录正在执行的虚拟机字节码的地址;

虚拟机栈:方法执行的内存区,每个方法执行时会在虚拟机栈中创建栈帧;

本地方法栈:虚拟机的Native方法执行的内存区;

(2)线程共享区,包含以下2类

Java堆:对象分配内存的区域;

方法区:存放类信息、常量、静态变量、编译器编译后的代码等数据;

常量池:存放编译器生成的各种字面量和符号引用,是方法区的一部分。