JVM内存模型解析
内存结构示意图:
public class Dome{
public static void main(String[] args){
Student stu = new Student();
stu.study();
stu.hash();
stu = null;
}
}
在Dome类运行的全过程:
1、Dome类被javac解析成字节码被JVM识别
2、创建main线程时,占用的是虚拟机栈内存并开始运行main方法
3、如果遇到未见过的类(例如Dome、Student),会继续调用类加载过程,将类的原始信息(类的名称,方法、继承关系、成员变量等)存入方法区
4、new 对象Student存储在栈中(内存大小:计算成员变量预计所占的内存)
6、调用方法时,所需要的临时变量、方法参数都存入了虚拟机的栈帧内存中
7、调用方法时,会从方法区中得到该方法的字节码指令,并由解释器将字节码转换成机器码交由CPU执行
8、调用方法时,会将正在执行的指令行数存储在程序计数器中
9、对于虚拟机栈和本地方法栈,java所使用的Oracle的Hotspot虚拟机并未划分详细,调用本地方法hash同样使用了虚拟机栈的内存。
10、调用方法时,方法多次调用,解释器同样多次调用浪费资源,所有对于热点方法会用到即时编译器来编译
11、当对象不再使用的时候,内存不足时会触发GC回收机制回收堆内存空间。
会出现内存溢出的部分
注意:程序计数器不会发生内存溢出
抛出OutOfMemoryError错误:
堆内存:当对象不断被创建并且一直被占用时
虚拟机栈:虚拟机栈中每个线程占1M内存,当线程的个数越来越多而长时间运行不销毁
方法区:加载的类越来越多
总结:
方法区主要负责存放类加载时的相关信息
虚拟机栈负责线程、临时变量、临时参数的存放
堆负责存放对象
程序计数器负责记录程序运行的位置