什么是JVM的运行时数据区:

看下图:

java虚拟机在该虚拟机进程运行过程中定义了各种各样的运行时数据区。用于存储java程序运行时各种不同的数据。有些运行时数据区是在java虚拟机进程开始时就创建,进程结束时销毁,但是一些运行时数据区是在线程创建时跟着创建,线程终止时销毁。

JVM六大运行时数据区:

  1. 堆。
  2. 方法区。
  3. 虚拟机栈。
  4. 本地方法栈。
  5. 程序计数器。
  6. 运行时常量池。

由于运行时常量池是在方法区中分配的,所以又通常会分为五大运行时数据区。

堆(Heap):

定义:

  1. 堆是java虚拟机所管理的内存中最大的一块,在虚拟机进程启动时创建,在虚拟机进程终止时销毁,被所有的线程共享。
  2. 几乎所有的java对象实例以及数组都在堆上分配。
  3. 当堆无法满足内存分配的需求时,将会抛出OutOfMemoryError异常。

方法区(Method Area):

定义:

  1. 方法区会在虚拟机进程启动时创建,在虚拟机进程终止时销毁,被所有线程共享。
  2. 方法区主要用于存储已经被虚拟机加载的类信息、常量(存储在运行时常量池中)、静态变量、编译器编译后的代码,一些元信息等数据。
  3. 虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫作Non-heap(非堆),主要目的是跟java堆区分开来。
  4. 当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
  5. 方法区在jdk 8 中就是metaspace(元空间),在jdk6或7中就是Perm Space(永久代)。
  6. 运行时常量池在方法区中分配。

运行时常量池(Runtime constant Pool):

运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

虚拟机栈(Java Virtual Machine Stacks)

定义:

  1. 虚拟机栈是一个线程执行的区域,是一个先进后出数据结构,保存着一个java线程的调用状态。换句话说,一个java线程的运行状态是由一个虚拟机栈保存的。所以虚拟机栈是线程私有的,随着线程的创建而创建,随着线程的终止而销毁。
  2. 虚拟机栈中存储的结构是栈帧(后面讲解)。
  3. 一个方法的执行开始,会把一个栈帧压入虚拟机栈中,方法执行完成时就把栈帧弹出虚拟机栈。
  4. 假如有如下代码:
public class XuNiJiZhan {public static void a(){d();}public static void c(){}public static void d(){c();}public static void main(String[] args) {a();}
}

那么大概的线程就是这样:


解释:

  1. 从代码看出 线程先执行main方法,所以把main方法的栈帧压入虚拟机栈。
  2. 然后main方法中调用a方法,所以把a方法的栈帧压入虚拟机。
  3. 然后a方法调用d方法,所以把d方法的栈帧压入虚拟机。
  4. 然后d方法调用c方法,所以把c方法的栈帧压入虚拟机。
  5. 待得c方法执行完并返回时,c方法的栈帧会弹出,其他方法以此类推,直至虚拟机栈帧为空。

注意:

  1. 当一个线程的方法调用链太长,也就是说压入虚拟机栈的栈帧数量太大,超出一定数量时,就会报出StackOverflowError异常。
  2. 如果虚拟机可动态扩展的话,如果扩展时申请不到足够的内存,将会报出OutOfMemoryError异常。

栈帧:

  1. 每一个栈帧就对应一个一个方法的调用,可以理解为一个方法的运行空间。
  2. 每个栈帧中包括局部变量表、操作数栈(先进后出的栈结构)、动态链接(执行运行时常量池的引用),方法返回地址和一些附加信息。
  3. 局部变量表:存放了编译期可知的各种基本数据类型(int、double、char、float、boolean、short、byte、long)和对象引用、还有returnAddress(指向了一天字节码指令地址)。
  4. 对64位的double和long会占用两个局部变量空间(可以看作局部变量表的内存单位)。其余的数据类型占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法的栈帧的局部变量表所需的内存空间大小是完全确定的,且在方法运行区间不会改变。
    看以下代码:
public class ZhanZhen {public static int testFrame(){int p1 = 3;int p2 = 5;int result = p1 + p2;return result;}public static void main(String[] args) {System.out.println(testFrame());}
}

javap反编译后代码以下字节码指令(取testFrame方法部分,对照源码看食用效果更佳):

public static int testFrame();descriptor: ()Iflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=3, args_size=00: iconst_3      //将int型3压入操作数栈栈顶。1: istore_0     //将操作数栈栈顶数值弹出并存入局部变量表中的第一个局部变量中。2: iconst_5   //将int型5压入操作数栈栈顶。3: istore_1    //将操作数栈栈顶数值弹出并存入局部变量表中的第二个局部变量中。4: iload_0   //将局部变量表第一个局部变量的值压入操作数栈中。5: iload_1  //将局部变量表第二个局部变量压的值入操作数栈中。6: iadd     //将栈顶的两个int型数值弹出并相加,相加后的值压入栈顶中。7: istore_2   //将操作数栈栈顶数值弹出并存入局部变量表中的第三个局部变量中。8: iload_2   //将局部变量表第三个局部变量的值压入操作数栈中。9: ireturn   //方法返回操作数栈栈顶的值。

本地方法栈(Native Method Stacks):

基本效果与虚拟机栈相似。只不过它是在线程执行本地native方法时才会使用该栈,也是线程私有的。

程序计数器(The PC Register):

  1. 占据一块较小的内存,记录着当前线程执行的虚拟机字节码指令地址。如果执行的方法时native方法,则该计数器为空。
  2. 因为在多线程环境下,cpu的调度会使得线程间切换。所以为了能在每个线程重新获取cpu时间片时能继续执行。所以每个线程会有一个记录当前执行的指令地址的程序计数器,使得线程能够继续执行。
  3. 每个线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。
  4. 此内存区域是唯一一个在java虚拟机规范中没有任何规定OutOfMemoryError情况的区域。

谢谢查看。一起进步,加油!!!

JVM初学之JVM的运行时数据区相关推荐

  1. 从头开始学习->JVM(八):运行时数据区(下)

    前言 在上一篇文章中,我们了解到了JVM的运行时数据区,基本被划分了5个区域. 程序计数器(pc寄存器) java虚拟机栈 本地方法栈 java堆 方法区(永久代,元空间). 而上一篇文章中,我们详细 ...

  2. JVM Runtime Data Area(运行时数据区中的堆/栈/方法区讲解)

    JVM的组成 JVM由4大部分组成:ClassLoader .Runtime Data Area .Execution Engine .Native Interface.我们这里重点讲得是Runtim ...

  3. 【jvm系列-04】精通运行时数据区共享区域---堆

    JVM系列整体栏目 内容 链接地址 [一]初识虚拟机与java虚拟机 https://blog.csdn.net/zhenghuishengq/article/details/129544460 [二 ...

  4. Java -----JVM运行时数据区

    一.JVM体系结构 想要了解运行时数据区,先关注一下JVM的体系结构,知道数据区在JVM的整体位置和作用. 二.JVM运行时数据区 1.程序计数器 一块较小的内存空间,它是当前线程所执行的字节码的行号 ...

  5. JVM(类加载、运行时数据区、堆内存、方法区、本地接口、执行引擎和垃圾回收)java虚拟机(JVM)的超详细知识点

    JVM虚拟机 一.JVM的概述 1.为什么要学习JVM 2.虚拟机 3.JVM的作用 作用 特点 4.JVM的位置 5.JVM的分类 6.各个组成部分的用途 7.Java 代码的执行流程 8.JVM ...

  6. 20张图助你了解JVM运行时数据区,你还觉得枯燥吗?

    我们的JVM系列已经断更好几天了,小伙伴们在后台疯狂私信阿Q,想看后续内容,今天它来了.相信大家在上篇文章中已经对类加载子系统有了清晰的认识,接下来就让我们来揭开"运行时数据区"的 ...

  7. JVM运行时数据区---方法区(演变和垃圾回收)

    方法区演进细节与垃圾回收 方法区演进细节 永久代演进过程: 首先明确:只有 Hotspot 才有永久代.BEA JRockit.IBMJ9 等来说,是不存在永久代的概念的.原则上如何实现方法区属于虚拟 ...

  8. JVM运行时数据区---方法区(前言)

    运行时数据区-方法区 方法区内部结构 方法区的演变和垃圾回收 前言 方法区是运行时数据区的最后一个部分. 从线程共享与否的角度来看: ThreadLocal:如何保证多个线程在并发环境下的安全性?典型 ...

  9. JVM运行时数据区---堆(堆内存)

    运行时数据区-堆 JVM 堆的对象分配过程 堆中TLAB为对象分配内存 堆-逃逸分析与代码优化 堆的核心概念 <Java虚拟机规范>中对Java堆的描述是:所有的对象实例以及数组都应当在运 ...

最新文章

  1. 【blender教程】从头到尾全流程创建一辆吉普车
  2. graphpad两组t检验_Graphpad 作图教程 | 手把手教你绘制森林图
  3. 内网能PING通TELNET通不能访问解决
  4. 分布式mysql一致性问题_分布式缓存数据库一致性问题
  5. 编写java的应用_编写Java应用程序
  6. ubuntu下idea后台执行的方法
  7. Newtonsoft.Json日常用法
  8. windows服务器系统巡检脚本,sql server 数据库巡检脚本
  9. android加载富文本可点击链接,Android富文本解析器,支持网络图片,图片和链接点击事件...
  10. 万豪国际数据再遭泄露影响520万客户,两名员工账户为突破口
  11. java实例摘要(四)
  12. 一张图看懂你与AI的优劣势
  13. 需求分析文档、概要设计文档、详细设计文档
  14. 算法设计与分析——prim算法
  15. tvm relay inline pass的调研
  16. operators库
  17. Will----个人资料
  18. 两个无线路由器的连接(修订)
  19. 任正非:副职要精于管理,正职要敢于进攻
  20. 内热外寒感冒,不能乱吃药

热门文章

  1. 【codevs1026】逃跑的拉尔夫,广搜的胜利
  2. 使用to like动词_17
  3. 2017.9.8 字符串 失败总结
  4. 【英语学习】【Daily English】U14 Transportation L01There will be a car exhibition next month
  5. 【英语学习】【Daily English】U07 Restaurant L04 It's on me today.
  6. Intel Sandy Bridge/Ivy Bridge架构/微架构/流水线 (5) - 流水线前端传统译码器
  7. 基于 Spring 实现管道模式的最佳实践
  8. wcf编程用什么工具_四个强大的自学编程网站工具,用的人都是学习欲望很强!...
  9. linux so 库的生成与调用
  10. 中软python编码规范考试试题_这些常见的python学习问题,你中枪了吗?