什么是JVM?
JVM全程Java Virtual Machine,java虚拟机,是一种软件模拟运行在隔离环境中的计算机系统。
常见的虚拟机:VMWare,VirtualBox等。
JVM和这些虚拟机的区别:VMware是软件模拟CPU指令集,而且有很多的物理寄存器。但是JVM是软件模拟java的字节码(相当于CPU的指令),只是模拟了程序计数器。
了解java内存使用的必要性:
Java内存是由Java虚拟机控制的,一旦出现了内存泄漏或内存溢出,排查错误将会非常艰难。
HotSpot是Java默认的JVM
他发布于JDK1.3。
Java虚拟机所管理的内存包含以下几个运行时的内存区域。
程序计数器:
在PC里面指示的是当前执行指令的地址,在Java里面相当于字节码的行号指示器(Java类会被编译成字节码.class文件),程序计数器占用的空间比较小。
虚拟机栈(会发生OOM和StackOverFlowError栈请求深度过大异常):
虚拟机栈就是栈,存放的是局部变量表(每一个方法执行时都会创建一个栈帧,用来存放方法中用到的局部变量),和操作数,动态链接,方法出口地址(存放在栈底,方法执行完毕之后就会返回,方法出口就是跳到调用方法处下一条指令的地址)。
局部变量表(虚拟机栈的一部分,编译期间已知大小):存放编译期间大小可知的8大数据类型(byte char short int float double long boolean),和对象引用(对象引用占空间一样)。
本地方法栈:
用于服务native方法,HotSpot中,将本地方法栈和虚拟机栈合二为一。
Java堆(动态扩展,会发生OOM异常):
Java虚拟机启动的时候就会创建一个Java堆,Java堆和JVM是一一对应的。
Java堆用于保存对象实例和对象数组。是垃圾回收器管理的主要区域。物理上可能不连续。
方法区:
存储已经被加载的类信息,运行时常量池,静态变量static。和即时编译器编译后的代码,JDK1.8后被称为元空间。此区域的垃圾回收指常量回收,和类卸载。
运行时常量池(方法区的一部分):
存放字面量(1, 0.0, "hello"这些),以及符号引用(public class, 方法描述符(public static void fun))。
以下是一个Java程序从编译到运行的全过程: