运行时数据区
运行时数据区主要分为五部分,
第一部分:程序计数器,可以看做是当前线程所执行字节码的行号知识器,线程私有;
第二部分:java虚拟机栈,描述的是java方法执行的线程模型,每个方法被执行时都会同步创建一个栈帧,用于存储局部变量表、动态连接、方法出口、操作数栈等信息。其中局部变量表用于存储编译期已知的基本数据类型、引用类型(reference类型,并不代表对象自身,可能是一个指向该对象起始内存地址的引用指针,也可能是一个指向该对象的句柄或其他和此对象相关的位置)和retrunAddress类型,是线程私有的;
第三部分:本地方法栈,和虚拟机栈高度类似,为本地native方法提供服务,是线程私有的;
第四部分:java堆空间,几乎存放了java世界的所有对象实例,是线程共享的。不过从内存分配的角度看,堆空间可以划分为多个线程私有的分配缓冲区(TLAB);
第五部分:方法区,存放了已被JVM加载的类型信息、常量、静态变量、即时编译器编译的代码缓存等,方法区的垃圾回收主要针对对常量的回收和对类型的卸载(什么是类型的卸载?)。
另外,延伸出两部分运行时常量池和直接内存。
运行时常量池属于方法区的一部分,主要用于存放编辑期间产生的字面量和符号引用;
直接内存不属于运行时数据区的一部分,不过java引入了一种基于通道与缓冲区的I/O方式,通过nativve函数库直接分配堆外内存,在堆空间中的DirectByteBuffer对象作为这块内存的引用,避免了在java堆和nvtive堆中来回复制数据,在某些场景显著提高性能。