一、JVM的运行机制概要
如果要运行Java程序,首先要编写Java的源文件(.java),之后Java的编译器将源文件编译成字节码文件(.class文件),之后再通过类加载器将字节码文件加载到jvm中,其中与程序运行最密切的是jvm中的运行时数据区(Runtime data area)。
二、运行时数据区(JVM内存模型)
程序计数器:
程序计数器是用于存放下一条指令所在单元的地址的地方
如果线程正在执行一个java方法,这个计数器记录的是正在执行虚拟机字节码指令的地址
虚拟机栈
该区域是线程私有的,虚拟机的生命周期和线程相同,在执行一个java方法的时候回在该区域创建一个栈帧,栈帧用来保存局部变量表(在方法中定义的变量或者方法的参数都是方法的局部变量)、动态链接、方法出口、操作数栈等等信息,其实每个方法从执行到执行完毕就是一个入栈与出栈的过程。
当入栈的速度大于出栈的速度的时候会出现栈内存溢出(Exception in thread “main” java.lang.StackOverflowError)。
·本地方法栈:
本地方法栈和虚拟机栈的作用很相似,不同点是虚拟栈是为Java方法服务的,本地方法栈是为native方法服务的(这种本地方法是没有方法体的,可以算是一个抽象方法,具体的实现是本地操作系统的c语言写的一些函数库中的方法实现的)
·堆:
堆是运行时数据区中最大的一块子区域,创建的实例对象和数组都需要在堆内存开辟空间,堆空间是线程共享的区域,该区域也是gc(垃圾回收)重要处理的一个区,所以堆又被称为“GC堆”
·方法区:
这是对永久代的实现,永久代是在JDK1.8之前出现的概念,在JDK1.8开始就没有了永久代,而是使用了元空间代替了。
方法区也是一块线程共享的区域,该区域主要保存的是已经加载到jvm中的类的信息、常量、静态变量等等。