Java运行时数据区域
运行内存分布
首先,在java虚拟机中,运行内存的分布主要有程序计数器
、java虚拟机栈
、本地方法栈
、java堆
、方法区
。
而程序计数器、java虚拟机栈、本地方法栈都是线程私有的,所以它们的生命周期随着线程的消失而消失,因此在垃圾回收中,就不需要回收这三个区域。这个我们后面再详细说明。
程序计数器
程序计数器用于记录当前虚拟机正在执行的方法,也就是记录虚拟机正在执行的虚拟机字节码指令的地址。
注:如果正在执行的方法是本地方法,则为空。
java虚拟机栈
java虚拟机栈是指每个java方法在执行的同时,会创建一个栈帧,这个栈帧存储了局部变量表、操作数栈、常量池引用等信息。每一个java方法的运行和结束就对应的入栈和出栈的一个过程。
本地方法栈
本地方法 栈与java虚拟机栈类似,但是,它是为本地方法服务的。本地方法一般就是指那些用其他语言,例如c、c++等语言编写的方法,并且被编译成为本机硬件和操作的程序,需要特殊处理。
java堆
java堆是java虚拟机中的一个重要的存储区域,大多数对象都是存储在java堆中,同时也是垃圾收集的最主要区域。
堆的内存分布不是连续的,也就是说,是可以动态增加其内存的,如增加内存失败,则会抛出outofmemoryerror异常。
方法区
方法区是用于存储被加载的类的信息、常量、静态变量、即时编译器编译后的代码等数据。
方法区与java堆一样,不需要连续的内存,而是可以动态扩展的,失败一样会抛出异常。
如果垃圾回收回收了这块区域,那主要是对常量池的回收和对类的卸载,但是,实现起来会比较难。
方法区中存储了常量,是因为方法区中还有一块区域,叫做:运行时常量池,这个区域用于存放运行时所产生的常量。运行时常量池和字节码常量池有所不同,运行时常量池会从字节码常量池中取常量进行存储,但不意味着运行时常量池的常量都是从字节码常量池中获取的,它也会在程序的运行期间将新的常量放进运行时常量池中。例如:string.intern()
方法,这个方法的作用就是:先从方法区中的运行时常量池查找是否存在该值,如果有,则返回该值,如果没有,则将该值放进运行时常量池中。
上一篇: 详解Docker在哪里保存日志文件