运行时数据区
java虚拟机将内存分为5个区域,堆区,方法区,虚拟机栈,本地方法栈,pc程序计数器。
堆区和方法区是多个线程共享的,虚拟机栈和本地方法栈和pc程序计数器是每个线程独有的,pc程序计数器只是为了记录下一个执行的字节码指令的地址。虚拟机栈是为了执行用户方法创建的,本地方法栈是为了执行本地方法创建的
pc程序计数器
pc程序计数器占内存中很小的一部分,记录下一条执行的字节码指令的地址。是线程独有的,一个线程一个。
java虚拟机栈
java虚拟机栈是线程独有的,里面存的是栈帧,每一个栈帧是在编译时就确定栈帧大小的.栈帧里存的主要是局部变量表,局部变量表里存的是变量long和double占用两个slot,其余的基础类型占用一个slot,还会存对象引用(reference类型),并不是对象本身,可能是对象地址或者是句柄.
本地方发栈
本地方法栈和虚拟机栈发挥的作用非常相似.区别只是在于本地方法栈是为了Java虚拟机执行本地方法(本地方法就是用其他代码写的方法,比如c++代码)而虚拟机栈是为了执行java方法
java堆
堆区主要是对象分配的区域,所有的对象实例都是在堆区分配的,有一些虚拟机垃圾收集器把堆区分为,老年代和新生代,其中新生代有eden区和survivor区其中survivor区还有fromspace和tospace他俩的比例是1:1,堆空间中还有一种思想因为多个线程在创建对象时可能会导致内存划分时的线程安全问题,所以堆内存中可能会存在提前给每个内存分配线程缓冲区,就是提前为每个线程分配内存,但是java虚拟机规范并没有规定堆区是如何划分的,G1垃圾收集器就没有采用这种分代的理念,java虚拟机规范中只要求堆区内存是在逻辑上是连续的,并没有要求物理上连续,但是大部分实现虚拟的的厂商还是选择物理上连续
方法区
方法区这部分内存主要存放类型信息,静态变量,和运行时常量池,类型信息就是描述一个类的信息,而运行时常量池主要存放字面量和符号引用.
java虚拟机规范中把方法区规定为堆区的一个逻辑部分,但是方法区有一个别名叫做非堆
方法区也被很多人叫做永久代,后来又被叫做元数据空间(jdk8以后,hotspot虚拟机实现采用元空间来实现方法区)
运行时常量池(方法区内的)
这部分区域主要放字面量和符号引用,说白了就是名字,各种类的名字和各种变量的名字.这部分区域主要是在方法区中.
直接内存
直接内存是独立于运行时数据区之外的一个内存,在jdk7以后出现了了一个directbytebuffer类,可以直接操纵直接内存.