JVM内存模型
线程独占:栈和本地方法栈、程序计数器;线程共享的是堆和方法区
栈:又叫方法栈,线程私有,线程执行方法都会创建一个栈阵,用来储存局部变量表,调用方法执行入栈,方法返回执行出栈
本地方法栈:与栈类似,保存执行方法信息,执行java方法是使用栈,native方法使用本地方法栈
程序计数器:保存当前线程执行的字节码位置(也就是程序执行到哪里了),只为java方法服务,每个线程你有自己的计数器
堆:存放由new创建的对象和数组,动态地分配内存大小,会有垃圾收集器自动回收数据,存取速度较慢
方法区:存储被虚拟机加载的类信息,常量、静态变量。1.7的永久代和1.8的元空间都是方法区的实现,方法区是内存最大的一部分,被线程共享,存放对象的实例,当堆空间不足时,会抛出OOM异常
扩展
元空间
jdk8后,永久代被元空间替代,实际上两者都是方法区的实现。对于永久代,如果生成很多class的话,可能出现PerGen space异常,因为永久代的空间配置有限,是和堆的使用地址连续的,元空间的物理地址不再与堆连续,而存在与本地内存中,内存多大,元空间多大。
STW(Stop The World)
垃圾回收的过程中,会涉及到对象的移动,为了保证对象引用更新的正确性,必须停用所有的用户线程,这种停顿就是stw。
OpoMap
在HotSpot中,有一个映射表称为OopMap,一旦类加载动作完成,HotSpot就会把对象内的偏移量和数据类型等计算出来,记录到OpoMap中,在即时编译过程中,也会在特定的位置生成OpoMap,记录栈上和寄存器哪些位置是引用:循环的末;方法临返回前;可能抛出异常的位置。
TLAB本队线程分配缓存
把内存分配的动作按照线程划分在不同的空间内进行,每个线程在java堆中预先分配好一小块内存,这就是TLAB。通过:xxUseTLAB设置