JVM——JVM运行时数据区(JVM内存模型)

前言

Jvm这个系列的文章主要参考大佬Carson_Ho的JVM相关文章来总结《深入理解Java虚拟机这本书》的知识

Java虚拟机结构

java虚拟机如下第一张图片(JDK1.7及以前),JDK1.8及以后JVM结构中的运行时数据区中的内容有所变化,下面会提到这些变化。
java虚拟机包括运行时数据区域执行引擎本地接口本地方法库

类加载系统不属于Java虚拟机结构。

JVM运行时数据区(JVM内存模型)

Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域,按照其中存储的数据是否线程私有可以划分为两类:

虚拟机栈本地方法栈程序计数器都是线程私有

Java堆方法区线程共享的。

以下是JDK1.8以前的运行时数据区划分(注意运行时数据区是中间背景为蓝色的那部分):

jvm内存结构

作为对比,以下是JDK1.8及以后JVM的内存划分:

JVM内存模型

程序计数器

程序计数器是一块较小的内存空间,它是当前线程所执行的字节码的行号指示器

  • 作用:通过改变它的值来实现分支循环,跳转,异常处理,线程恢复等基础功能。

  • 可能抛出的异常:JVM规范中内存区域中唯一一个没有规定任何OOM异常的区域

  • 特点:线程私有


Java虚拟机栈

描述Java方法执行的内存模型:每个方法在执行时会在其中创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息。

  • 作用:用来存储局部变量表,操作数栈,动态链接,方法出口等信息。

  • 可能抛出的异常:StackOverflowError异常(线程请求的栈深度大于虚拟机所允许的深度时),OutOfMemoryError异常(JVM动态扩展无法申请到足够内存时)

  • 特点:线程私有,生命周期和线程相同


本地方法栈

本地方法栈和java虚拟机栈作用类似

  • 和java虚拟机栈的区别:描述native方法的内存模型

Java堆

垃圾收集器管理的主要区域,通常被称作”GC堆“

  • 作用:存放创建的Java对象实例
  • 特点:Jvm中内存最大,线程共享
  • 抛出异常:OOM异常(堆中没有内存完成实力分配并且无法再扩展时)
  • 堆的细分

内存回收角度:新生代(Eden,From Survivor和To survivor)和老年代

内存分配角度:多个线程私有的分配缓冲区


元空间

方法区只是JVM中的一个规范,是java堆的逻辑组成部分,垃圾收集在这个区域较少,还可以选择不进行GC。元空间和永久代本质上都是方法区的实现,只是在Java8中,元空间取代了永久代,同时元空间不再与堆连续,而且是存在于本地内存。

  • 作用:存放虚拟机加载的类信息,静态变量,常量等数据。
  • 特点:线程共享
  • 抛出异常:OOM异常(方法区无法满足内存分配需求时)

运行时常量池

运行时常量池是方法区的一部分。在jdk 1.6中,运行时常量池位于方法区中;1.7开始将运行时常量池放置于java堆中;1.8之后位于直接内存中的元空间中。

  • 作用:存放编译时生成的字面量和符号引用
  • 特点:动态性(运行期间也可能将新的常量放入池中,比如String类的intern方法)
  • 抛出异常:OOM(常量池无法申请到足够内存时)

直接内存
  • 定义:JDK1.4引入的NIO(New Input/Output)类引入的一种基于通道和缓冲区的I/O方式 通过使用Native函数库直接分配的堆外内存
  • 作用:避免在Java堆和Native堆中来回复制数据,提高了性能
  • 大小:理论上无限大,实际上还是受制于本机内存
  • 异常:OOM(物理内存满足不了它动态扩展申请的内存)

参考资料

JDK1.8 JVM运行时数据区域划分

JVM:图文详解Java虚拟机的内存结构

面试官,JAVA8 JVM内存结构变了,永久代到元空间

《深入理解Java虚拟机》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值