jvm-内存模型

71 阅读2分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

内存区域

程序计数器

当前线程锁执行的字节码的行号指示器,分支,循环,跳转,异常处理,线程恢复都需要依赖这个计数器。

线程私有,为了线程切换后能够恢复到正确的执行位置。

  • 方法类别

当正在执行的时Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址

当前正在执行的Native方法,计数器值为

java虚拟机栈

线程私有;生命周期与线程相同;

当每个方法被执行,栈会同步创建一个栈帧用于存储局部变量表,操作数栈,动态连,方法出口等信息。 被调用是入栈,执行完毕出栈。

  • 局部变量表

局部变量表存放编译期可知的各种基本数据类型对象引用地址字节码指令地址

存储空间以局部变量槽表示。64位的long和double类型占用两个槽,其他的占用一个。

在编译期间,完成局部变量表的内存空间

当执行一个方法时,方法分配局部变量表空间的大小(变量槽的数量)是确定的。

  • 异常

1.线程请求的深度大于栈的深度StackOverflowError异常

2.栈的容量可以扩展(但是HotSpot是无法扩展的),无法申请足够内存会OutOfMemoryError异常

  • jdk1.7之后

将永久代的字符串常量池静态变量等移至堆中,其他的内容(主要是类型信息)存放到元空间

堆时虚拟机管理的内存中最大的一块,线程共享

唯一目的存放对象实例

垃圾收集器管理的内存区域

从分配角度看,可以划分出多个线程私有的缓冲区,提升内存分配的效率

是可拓展的:-Xmx 和-Xms设定。

  • 异常

当堆中无法再拓展但是还有未分配的对象,就会OOM异常。

方法区

线程共享:存储已被加载的类信息常量静态变量,即时编译器编译后的代码缓存等数据。

方法区,在JDK8以前,被称呼为永久代,JDK1.8 之后,称为元空间

垃圾回收针对常量池的回收和对类型的卸载。

  • 异常

无法满足新的内存分配需求,跑出OOM异常。

运行常量池

是方法区的一部分。Class会将常量池表中的数据在类加载后存放在该区域中,包括字面量符号引用