运行时数据区:
- 程序计数器
- Java 虚拟机栈
- 本地方法栈
- Java堆
- 方法区
程序计数器(线程私有)
可以看做是当前线程所执行的字节码的行号指示器。在虚拟机概念模型里,字节码解释器工作时就是通过改变这个计数器的值来取下一条需要执行的字节码指令,分支、循环、跳转、异常等。
因为Java虚拟机的多线程是通过线程的轮流切换并分配处理时间的方式来实现,在任一时刻,一个处理器只能处理一个线程的指令。所以,为了是线程切换后恢复原来执行的位置,每个线程都有自己的程序计数器。
Java 虚拟机栈(线程私有)
她的生命周期和线程是一样的。
虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行时,都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接和接口等信息。
本地方法栈
和虚拟机栈的作用相似,区别是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈为虚拟机使用到的Native方法服务。
Java 堆(线程共享)
Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。
所有的对象实例和数组都要在堆上分配。
Java 堆是垃圾收集器管理的主要区域,因此也被称为 “GC堆”。
Java 堆细分:
- 新生代
- 老年代
再细分: - Eden 空间
- From Survivor 空间
- To Survivor 空间
方法区(线程共享)
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
-XX:MaxPermSize
运行时常量池
运行时常量池是方法区的一部。Class 文件中除了类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后进去方法去的常量池中存放。
运行时常量池,相对于 Class 文件常量池的一个重要特征就是具备动态性,不要求常量一定在编译器产生,运行时产生的常量也会放入常量池中。
例如 String 类的 intern() 方法。