一、什么是JVM?
JVM是运行所有Java程序的抽象计算机,是Java语言的运行环境,简单点说就是java程序是运行在JVM上的,JVM是一个抽象的计算机。
java语言有个重要的特性就是平台无关性,语言都要在计算机上编译成可识别的字节码文件,这样才能被计算机识别并运行。前面说过JVM就是一个抽象的计算机,java语言就在这个抽象的计算机上编译成了JVM可识别的字节码文件,JVM又可以安装在windows、linux、mac等系统上,所以java语言编译成的字节码文件可以在任何操作系统上执行。
二、JVM内存模型
JVM它主要包括五块区域,分别是程序计数器、java栈(虚拟机栈)、本地方法栈、堆、方法区。
堆和方法区各一个,堆和方法区是共享的;
每一个线程都有一个程序计数器、java栈和本地方法栈。
1、程序计数器:
程序计数器里面存放的是正在执行的字节码指令地址。
每一个线程都要存储一个当前执行指令的地址,这样才能在线程切换后能够恢复到正确的执行位置。单个线程还好说,就按照程序指令执行就好,但实际上,我们的电脑能同时运行多个程序,这就需要有多个线程并行运行,在时间片到的情况下,就会切去另一个线程执行,就是为了解决这个问题,才有的程序计数器。
2、java栈(虚拟机栈)
栈里存放的是当前线程中的局部变量、操作数栈、方法等,我们都知道栈是先进后出的规律,这样就解每个方法从调用直至完成最后被消除的过程,一个程序运行来说,他肯定是先把main函数进入栈中,在其中进行各种操作,最后当所有的指令都执行完成之后,main出栈,意味着这个线程的结束。
3、本地方法栈
本地方法栈与Java虚拟机栈非常相似,也是线程私有的,区别是虚拟机栈为虚拟机执行 Java 方法服务,而本地方法栈为虚拟机执行 Native 方法服务。
4、Java堆
5、方法区
用来存储已被虚拟机加载的类信息、常量、静态变量等数据。
三、内存解析
我们现在来分析一下下面这段代码是如何在内存中存储的
public class JvmDemo {
//声明一个常量finalIntVar,它的值为123456
final Integer finalIntVar = 123456;
//声明一个String型的变量,它是"global string"
String strInstanceVar = "global string";
//主函数
public static void main(String[] args) {
//在主函数中声明一个String型的变量,它是"main"
String strInMain = "main";
//new了一个String类型的对象,变量的值是hello
String str = new String("hello")
}
}
①首先我们先把java的栈、堆和方法区画出来
②他在类中声明了一个常量finalIntVar,它的值为123456和声明一个String型的变量,它是"global string",前面说过常量存储在方法区中,所以我方法区中存在了两个值,一个是123456,一个是global string
③这时有一个main函数进入栈中
④在main函数中声明了一个String型的变量,它是"main",那我们就在相应的方法区中创建一个叫作main的常量。由栈中的strInMain指向方法区中的main的地址。
⑤在main方法中new了一个String的对象,对象里的名字叫hello,实例对象都在堆中生成,所以在堆中创建了一片空间用来存储String类型的实例;由于这个实例中还有一个叫作"hello"的变量,那就由堆中对象在指向方法区中的hello变量。
以上就是代码在虚拟机上是如何存储的。
上面有不对的请给我留言哦噢噢噢噢