Java 虚拟机(JVM)的内存空间分为五个部分,分别是:
- 程序计数器
- Java 虚拟机栈
- 本地方法栈
- 堆
- 方法区。
1.程序计数器
概念:是一块较小的内存空间,程序计数器里面记录的是当前线程正在执行的那一条字节码指令的地址
作用:
- 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
- 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
2.Java虚拟机栈
概念:主要由局部变量表构成
特点:局部变量表的大小在编译时期就确定下来了
3.本地方法栈
功能和Java虚拟机栈类似,是本地方法运行的内存模型
4.堆
堆是用来存放对象的内存空间,整个 Java 虚拟机只有一个堆,所有的线程都访问同一个堆
5.方法区
是堆的一个逻辑部分。方法区中存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等
Java对象创建
- 检查常量池中是否有即将要创建的这个对象所属的类的符号引用(若常量池中没有这个类的符号引用,说明这个类还没有被定义。抛出ClassNotFoundException)
- 进而检查这个符号引用所代表的类是否已经被JVM加载(没有加载则加载,已加载则分配内存)
- 根据方法区中该类的信息确定该类所需的内存大小;
- 从堆中划分一块对应大小的内存空间给新的对象
- 为对象中的成员变量赋上初始值(默认初始化);
- 设置对象头中的信息;
- 调用对象的构造函数进行初始化;
此时,整个对象的创建过程就完成了。
垃圾回收
可达性分析法 :所有和GC Roots直接或间接关联的对象都是有效对象,和GC Roots没有关联的对象就是无效对象。
GC Roots是指:
Java虚拟机栈所引用的对象(栈帧中局部变量表中引用类型的变量所引用的对象)
方法区中静态属性引用的对象
方法区中常量所引用的对象
本地方法栈所引用的对象