运行时数据区域
方法区 堆 虚拟机栈 本地方法栈 程序计数器
常说的内存中的栈 即指虚拟机栈
本地方法栈为虚拟机使用到的native方法服务
java堆(Garbage Collected Heap)是被所有线程共享的一块内存区域,几乎所有的对象实例都在堆中存储;堆可以细分为新生代和老年代,再细致些可以分为 Eden空间、From Survivor空间、To Survivo空间等。
方法区(Method Area 、None-Heap)也是线程共享的内存区域,用于存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
运行时常量池(Runtime Constant Pool)是方法区的一部分,class文件中有一项信息为常量池,用于存放编译期生成的各种字面量和符号引用(初步理解 包括一些静态类的引用)。
(非运行时数据区域) 直接内存(Direct Memory)为Nio中直接分配的堆外内存
Hotspot虚拟机对象
对象创建
1.在堆中给新创建的对象分配内存时,要保证线程安全:一种采用cas加上失败重试,保证更新操作原子性;另一种每个线程在java堆中预先分配一小块内存(本地线程分配缓存)。
2.内存分配完成后,虚拟机为分配空间初始化值(0 null之类)。
3.然后虚拟机对对象做必要设置,将对象是那个类的实例、如果找到类的元数据信息、对象哈希码、gc分代年龄信息等存放在对象的对象头中。
对象内存布局
分为3块:对象头、实例数据和对齐填充(jvm自动内存管理系统要求对象起始地址为8字节的整数倍,对齐填充用来对齐)
对象头包括两部分信息:一部分是存储对象自身的运行时数据,如哈希码、gc分代年龄、锁状态标志等;另一部分是类型指针,即对象指向其类元数据的指针,通过这个确定对象是哪个类的实例。
对象访问定位
句柄访问和指针访问
指针:栈上的reference直接指向堆中实例对象,对象中包含类型指针
句柄:reference指向堆中的句柄池,句柄池包含对象实例的指针和对象类型的指针