Java内存区域与内存溢出异常小结
2017-10-07 18:36
204 查看
运行时数据区域
程序计数器
当前字节码的行号指示器线程私有
栈区
线程私有Java虚拟机栈
为虚拟机执行Java方法(即字节码)服务存储局部变量表、操作数栈、动态链接、方法出口等
局部变量表:编译期间完成分配
存储基本数据类型、对象引用
本地方法栈
为执行Native方法服务HotSpot将本地方法栈和虚拟机栈合一
Java堆
线程共享目的:存放对象实例
垃圾回收器管理的主要区域
通过-Xmx和-Xms动态扩展
方法区
虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等内存回收目标主要是针对常量池的回收和对类型的卸载(类型卸载较负载但必要)
运行时常量
存放编译期生成的各种字面量和符号引用
具有动态性:运行期间可以放入新的变量
直接内存
NIO类,可使用Native函数库直接分配堆外内存,通过存储在堆中的DirectByteBuffer对象作为这块内存的引用进行操作HotSpot虚拟机对象探秘
对象的创建
创建新对象(new 指令),先检查指令的参数能否在常量池中定位到类的符号引用,并检查是否被加载。如果没有,需进行类加载过程内存分配:
为新生对象分配内存:
内存规整:指针碰撞
内存不规整:空闲列表
并发情况下的线程安全:
对分配内存空间的动作进行同步处理,保证原子性
每个线程在Java堆中预先分配一小块内存,即本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。在每个线程自己的TLAB上分配内存,只有分配新的TLAB时,才需要同步锁定
对象的初始化和设置:
将分配的内存空间初始化为零值(使用TLAB可以在分配TLAB时初始化)
设置对象头
<init>方法,将对象按照程序员的意愿初始化
对象的内存布局
对象头Header:存储对象自身的运行时数据Mark Word:HashCode、GC分代年龄、锁状态标志、线程只有的锁、偏向线程ID、偏向时间戳等
类型指针:指向类元数据的指针,用于确定对象是哪个类的实例(非必要)
对齐填充(非必要):占位符,因为对象必须是8字节的整数倍
对象的访问定位
需要通过栈上的reference数据操作堆上的具体对象句柄访问:
在堆中划分一块内存作为句柄池,reference中存储对象的句柄地址,句柄中包含对象实例数据和类型数据各自的具体地址信息
优点:稳定的句柄,在对象移动(如gc操作)时,不需要改变reference
直接指针访问:
堆对象的布局中需要考虑如何放置类型数据,reference中存储的是对象实例数据地址
优点:速度快,节省了指针定位的时间开销(HotSpot)
相关文章推荐
- 深入理解JVM笔记一-java内存区域与内存溢出异常
- 深入理解JVM——java内存区域与内存溢出异常
- 第2章 Java内存区域与内存溢出异常
- Java内存区域、内存溢出异常和对象创建、布局、访问全过程
- 第二章 Java内存区域与内存溢出异常
- JVM高级特性与实践(一):Java内存区域 与 内存溢出异常
- Java内存区域与内存溢出异常
- 《JAVA虚拟机》读书笔记之Java内存区域与内存溢出异常
- JVM学习笔记(1)——Java内存区域与内存溢出异常
- Java内存区域与内存溢出异常
- java内存区域与内存溢出异常
- jvm(1)----java内存区域与内存溢出异常
- 深入理解Java虚拟机(一)Java内存区域与内存溢出异常
- 部分笔记—Java内存区域与内存溢出异常
- JVM之Java内存区域与内存溢出异常
- Java内存区域和内存溢出异常
- # 2 java内存区域与内存溢出异常
- JVM高级特性与实践(一):Java内存区域 与 内存溢出异常
- Java内存区域与内存溢出异常
- 1 Java内存区域与内存溢出异常