1、程序计数器(PCR)
JVM就是通过读取程序计数器的值来决定下一条需要执行的字节码指令。
每个线程都需要有一个独立的PCR,各线程间互不影响。
唯一没有内存溢出的区域。
(为了多线程而生的,单线程情况下完全不需要他。程序计数器是每个线程独有的,并非线程共享的,是线程安全的。)
2、栈内存
以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈和出栈。
某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。在线程执行一个方法时,它会跟踪当前类和当前常量池。此外,当虚拟机遇到栈内操作指令时,它对当前帧内数据执行操作。
每当线程调用一个Java方法时,虚拟机都会在该线程的Java栈中压入一个新帧。而这个新帧自然就成为了当前帧。在执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等数据。
return或者抛出异常时弹出当前帧。
线程私有的。任何线程都不能访问另一个线程的栈数据,因此我们不需要考虑多线程情况下栈数据的访问同步问题。当一个线程调用一个方法时,方法的的局部变量保存在调用线程Java栈的帧中。只有一个线程能总是访问那些局部变量,即调用方法的线程。
3、本地方法栈
跟上述栈内存一样,但是他是面对JVM的native方法。
4、堆内存
堆内存用于存放由new创建的对象和数组,在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。
所有线程共享,在JVM启动时创建。
5、方法区(内有运行时常量池:常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。)
当jvm使用类装载器装载某个类时,它首先要定位到对应的class文件,然后读入这个class文件,最后提取该文件的内容信息,并将这些信息存储到方法区,最后返回一个class实例。
存储类的描述信息(类的全限定名,访问修饰符,字段,方法等)。
6、直接内存